Re: [PATCH 02/10] accel/tcg: move cpu_reloading_memory_map into cpu-exec-softmmu

2023-03-21 Thread Alessandro Di Federico via
On Mon, 20 Mar 2023 10:10:27 +
Alex Bennée  wrote:

> This doesn't save much as cpu-exec-common still needs to be built
> per-target for its knowledge of CPUState but this helps with keeping
> things organised.

> --- /dev/null
> +++ b/accel/tcg/cpu-exec-softmmu.c

Could `cpu_reloading_memory_map` be pushed closer to its only user
(softmmu/physmem.c) instead of creating a new file in accel/tcg?

Maybe I'm missing something, but I see other usages of current_cpu in
softmmu:

$ git grep 'current_cpu->' softmmu/|cat
softmmu/cpus.c:current_cpu->stop = true;
softmmu/memory.c:return current_cpu->cpu_index;
softmmu/runstate.c:current_cpu->crash_occurred = true;

Maybe you envision more stuff in cpu-exec-softmmu.c.

Reviewed-by: Alessandro Di Federico 

-- 
Alessandro Di Federico
rev.ng Labs



Re: [PATCH v2 30/32] contrib/gitdm: add revng to domain map

2023-03-15 Thread Alessandro Di Federico via
On Wed, 15 Mar 2023 17:43:29 +
Alex Bennée  wrote:

> +rev.ng  revng

Can we have "rev.ng Labs"?
I suggested this in my previous e-mail too, but maybe it slipped away.

-- 
Alessandro Di Federico
rev.ng Labs



Re: [PATCH v2 08/10] contrib/gitdm: add revng to domain map

2023-03-10 Thread Alessandro Di Federico via
On Fri, 10 Mar 2023 18:03:30 +
Alex Bennée  wrote:

> +rev.ng  revng

Please use "rev.ng Labs". Thanks!

Reviewed-by: Alessandro Di Federico 

-- 
Alessandro Di Federico
rev.ng Labs



Re: [RFC] Reducing NEED_CPU_H usage

2023-01-12 Thread Alessandro Di Federico via
On Tue, 10 Jan 2023 11:56:50 -0800
Richard Henderson  wrote:

> However, at some point we do want to keep some target addresses in
> the proper size.  For instance within the softmmu tlb, where
> CPUTLBEntry is either 16 or 32 bytes, depending.

So that would be an optimization if `HOST_LONG_BITS == 32 &&
TARGET_LONG_BITS == 32`, correct?

I've heard about dropping 32 bit hosts multiple times here and there.
Maybe we could start with dropping oversized guests, which AFAIU are
the real offenders for most (all?) of these situations.

> > ## `abi_ulong`
> > 
> > Similar to `target_ulong`, but with alignment info.  
> 
> Pardon?  There's no alignment info in abi_ulong.

From include/exec/user/abitypes.h:

typedef uint32_t abi_ulong __attribute__((aligned(ABI_LONG_ALIGNMENT)));
typedef target_ulong abi_ulong __attribute__((aligned(ABI_LONG_ALIGNMENT)));

I thought that was the difference. Thanks for the clarification.

> This one requires some work within tcg/ to handle two target address
> sizes simultaneously. It should not be technically difficult to
> solve, but it does involve adding a few TCG opcodes and adjusting all
> tcg backends.

I'm a bit confused by this, do backends for some reason have
expectations about the address size?
Wouldn't this be enough?

diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 019fab00ccb..175162b8fef 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -29,0 +29,0 @@
@@ -2827,17 +2843,17 @@ static inline MemOp tcg_canonicalize_memop(MemOp op, 
bool is64, bool st)
 return op;
 }
 
-static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr,
+static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv_dyn addr,
  MemOp memop, TCGArg idx)
 {
 MemOpIdx oi = make_memop_idx(memop, idx);
-#if TARGET_LONG_BITS == 32
-tcg_gen_op3i_i32(opc, val, addr, oi);
-#else
-if (TCG_TARGET_REG_BITS == 32) {
-tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), oi);
-} else {
-tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_i64_arg(addr), oi);
-}
-#endif
+if (addr.size == 32) {
+tcg_gen_op3i_i32(opc, val, addr.i32, oi);
+} else {
+if (TCG_TARGET_REG_BITS == 32) {
+tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr.i64), 
TCGV_HIGH(addr.i64), oi);
+} else {
+tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_i64_arg(addr.i64), oi);
+}
+}
 }


> This forgets that both TCGv_i32 and TCGv_i64 are represented by
> TCGTemp,

https://i.imgflip.com/777wax.jpg

> which contains 'TCGType type' to discriminate.  This is not
> exposed to target/, but it's there.
> 
> Anyway, there's no need for this.

So, if I got it right, we could just make TCGv become a new opaque
type, propagate it down until the spot where we actually need to know
its size and then just have some `TCGTemp *tcgv_temp(TCGv v)` function
to inspect the actual size?

Makes sense!

> Before CPUNegativeOffsetState, we had all of those variables within
> CPUState, and even comments that they should remain at the end of the
> struct.  But those comments were ignored and one day icount_decr was
> too far away from env for easy addressing on arm host. Luckily there
> was an assert that fired, but it didn't get caught right away.

How comes it wasn't caught immediately?
We could have something like:

QEMU_BUILD_BUG_MSG(&ArchCPU.env - &ArchCPU.neg.tlb
   < DESIRED_THRESHOLD)

> > # Current status
> > 
> > We currently have a branch where we can build (but not link nor
> > run) a `x86_64-linux-user` configuration where `NEED_CPU_H` is
> > defined only for translation units in `target/` and `linux-user/`.  
> 
> This effort should be exclusive to system mode -- don't consider
> *-user at all. Each linux-user target bakes in not just target
> architecture parameters, which are complicated enough, but also C
> ABI, and kernel API.  Moreover, the most common use case for
> linux-user is a statically linked binary that operates within a
> chroot.

Our current goal is to get the following compilation unit to build
without NEED_CPU_H:

trace/control-target.c
gdbstub/gdbstub.c
cpu.c
disas.c
page-vary.c
tcg/optimize.c
tcg/region.c
tcg/tcg.c
tcg/tcg-common.c
tcg/tcg-op.c
tcg/tcg-op-gvec.c
tcg/tcg-op-vec.c
fpu/softfloat.c
accel/accel-common.c
accel/tcg/tcg-all.c
accel/tcg/cpu-exec-common.c
accel/tcg/cpu-exec.c
accel/tcg/tb-maint.c
accel/tcg/tcg-runtime-gvec.c
accel/tcg/tcg-runtime.c
accel/tcg/translate-all.c
accel/tcg/translator.c
accel/tcg/user-exec.c
accel/tcg/user-exec-stub.c
accel/tcg/plugin-gen.c
plugins/loader.c
plugins/core.c
plugins/api.c

They are subset of `arch_srcs` from `meson.build`.

Making them target agnostic for *-user too should be easy and could save
some build time.
But yeah, we'll now focus on system-mode.

We'll now try to sort out things from the easiest to the most complex
and start send

Re: [PATCH] Update scripts/meson-buildoptions.sh

2023-01-03 Thread Alessandro Di Federico via
On Tue, 3 Jan 2023 10:51:36 -0500
Stefan Hajnoczi  wrote:

> QEMU's Makefile used to a use a technique where it generated
> "timestamp" files and used cmp(1) to check if rebuilding was
> necessary:
> 1. Always generate meson-buildoptions.sh-timestamp.

`meson-buildoptions.sh-timestamp` would be the full expected output,
right? It's not just a date or something.
AFAIU that would make sure that if nothing changed in the output you
don't trigger other targets depending on `meson-buildoptions.sh`. It's
a solution for a different problem.

The problem with always rebuilding `meson-buildoptions.sh` is that we
spend 1 extra second on every build, even those that doesn't need to
rebuild anything else.
Not unacceptable, but I think we should strive not to commit generated
files and move the file to the build directory, unless there's a reason
why this is not viable that I'm not seeing.

-- 
Alessandro Di Federico
rev.ng Labs



Re: [RFC PATCH] docs: add some details about compilation units to coding style

2023-01-03 Thread Alessandro Di Federico via
Makes sense to me.

Reviewed-by: Alessandro Di Federico 

On Tue,  3 Jan 2023 10:47:58 +
Alex Bennée  wrote:

> +"Templates" and generated code
> +==
> +
> +We make heavy use of C's macro facilities combined with multiple
> +inclusion to generate code. This tends to use header files (usually
> +with the .inc suffix) with different #define'd constants. While the
> +use of C11's _Generic keyword has improved things a bit this
> technique +is still best suited to repetitive boiler plate code. If
> more complex +code generation is required consider using a script to
> generate it, +see for example the decodetree and qapi header scripts.

Consider adding reference to an example to make the situation more
explicit and less scary.

Here's an example that hopefully won't become outdated within yesterday:

$ git grep -B10 '#include.*\.inc'
fpu/softfloat.c-#define N 64
fpu/softfloat.c-#define W 128
fpu/softfloat.c-
fpu/softfloat.c:#include "softfloat-parts-addsub.c.inc"
fpu/softfloat.c:#include "softfloat-parts.c.inc"
fpu/softfloat.c-
fpu/softfloat.c-#undef  N
fpu/softfloat.c-#undef  W
fpu/softfloat.c-#define N 128
fpu/softfloat.c-#define W 256
fpu/softfloat.c-
fpu/softfloat.c:#include "softfloat-parts-addsub.c.inc"
fpu/softfloat.c:#include "softfloat-parts.c.inc"

-- 
Alessandro Di Federico
rev.ng Labs



Re: [PATCH] Update scripts/meson-buildoptions.sh

2023-01-03 Thread Alessandro Di Federico via
On Tue, 3 Jan 2023 09:37:51 -0500
Stefan Hajnoczi  wrote:

> I don't understand the issue. Can you describe the steps that cause
> meson-buildoptions.sh to become out-of-sync with meson_options.txt?
> 
> This will continue to be a problem in the future. Is there a way to
> fix it permanently?

In Makefile we have:

$(SRC_PATH)/scripts/meson-buildoptions.sh:$(SRC_PATH)/meson_options.txt

(Cc'ing Paolo since he's the author of this line)

This means make will regenerate
`$(SRC_PATH)/scripts/meson-buildoptions.sh` if its last modification
date is older than `$(SRC_PATH)/meson_options.txt`.

However these files are in the source directory, so this will behave
properly only under certain circumstances.

For instance if, for some reason, someone committed a new version of
`meson_options.txt` but not of `meson-buildoptions.sh`, a fresh clone
of the repo will not have the dates set correctly to trigger the
Makefile rule above:

$ ls -ln scripts/meson*
-rw-r--r-- 1 1000 1000 28913 Jan  3 15:58 scripts/meson-buildoptions.sh
-rw-r--r-- 1 1000 100091 Jan  3 15:58 scripts/meson.build

This is because git does not update file dates depending on the last
commit changing them.

This, on top of the fact that invoking `ninja` does not trigger
regeneration (which works for most other use cases), leads to a good
chance of forgetting to update meson-buildoptions.sh.

We could add the target to ninja to mitigate the risk, but still, the
dates problem remains.

An alternative solution would be to avoid committing generated files and
simply regenerating it every time.

On my machine `meson.py introspect --buildoptions` +
`scripts/meson-buildoptions.py` take 1.070s.
`./configure --help` takes 0.162s, so it's a bit sad.
On the other hand an actual invocation of configure can take
significantly longer (`./configure` takes 29.150s on my machine).

To avoid re-running it every time we could invoke `make
update-buildoptions` in `configure` but keep
`scripts/meson-buildoptions.sh` in the build directory.

-- 
Alessandro Di Federico
rev.ng Labs



[PATCH] Update scripts/meson-buildoptions.sh

2023-01-02 Thread Alessandro Di Federico via
Note: `Makefile` relies on modification dates in the source tree to
detect changes to `meson_options.txt`. However, git does not track
those. Therefore, the following was necessary to regenerate
`meson-buildoptions.sh`:

touch meson_options.txt
cd "$BUILD_DIR"
make update-buildoptions

Signed-off-by: Alessandro Di Federico 
---
 scripts/meson-buildoptions.sh | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index aa6e30ea911..0f71e92dcba 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -10,6 +10,9 @@ meson_options_help() {
   printf "%s\n" '   affects only QEMU, not tools like 
qemu-img)'
   printf "%s\n" '  --datadir=VALUE  Data file directory [share]'
   printf "%s\n" '  --disable-coroutine-pool coroutine freelist (better 
performance)'
+  printf "%s\n" '  --disable-hexagon-idef-parser'
+  printf "%s\n" '   use idef-parser to automatically 
generate TCG'
+  printf "%s\n" '   code for the Hexagon frontend'
   printf "%s\n" '  --disable-install-blobs  install provided firmware blobs'
   printf "%s\n" '  --docdir=VALUE   Base directory for documentation 
installation'
   printf "%s\n" '   (can be empty) [share/doc]'
@@ -40,7 +43,8 @@ meson_options_help() {
   printf "%s\n" '  --enable-trace-backends=CHOICES'
   printf "%s\n" '   Set available tracing backends 
[log] (choices:'
   printf "%s\n" '   
dtrace/ftrace/log/nop/simple/syslog/ust)'
-  printf "%s\n" '  --firmwarepath=VALUESsearch PATH for firmware files 
[share/qemu-firmware]'
+  printf "%s\n" '  --firmwarepath=VALUESsearch PATH for firmware files 
[share/qemu-'
+  printf "%s\n" '   firmware]'
   printf "%s\n" '  --iasl=VALUE Path to ACPI disassembler'
   printf "%s\n" '  --includedir=VALUE   Header file directory [include]'
   printf "%s\n" '  --interp-prefix=VALUEwhere to find shared libraries 
etc., use %M for'
@@ -93,7 +97,7 @@ meson_options_help() {
   printf "%s\n" '  glusterfs   Glusterfs block device driver'
   printf "%s\n" '  gnutls  GNUTLS cryptography support'
   printf "%s\n" '  gtk GTK+ user interface'
-  printf "%s\n" '  gtk-clipboard   clipboard support for GTK (EXPERIMENTAL, 
MAY HANG)'
+  printf "%s\n" '  gtk-clipboard   clipboard support for the gtk UI 
(EXPERIMENTAL, MAY HANG)'
   printf "%s\n" '  guest-agent Build QEMU Guest Agent'
   printf "%s\n" '  guest-agent-msi Build MSI package for the QEMU Guest Agent'
   printf "%s\n" '  hax HAX acceleration support'
@@ -156,6 +160,8 @@ meson_options_help() {
   printf "%s\n" '  usb-redir   libusbredir support'
   printf "%s\n" '  vde vde network backend support'
   printf "%s\n" '  vdi vdi image format support'
+  printf "%s\n" '  vduse-blk-export'
+  printf "%s\n" '  VDUSE block export support'
   printf "%s\n" '  vfio-user-server'
   printf "%s\n" '  vfio-user server support'
   printf "%s\n" '  vhost-cryptovhost-user crypto backend support'
@@ -164,8 +170,6 @@ meson_options_help() {
   printf "%s\n" '  vhost-user  vhost-user backend support'
   printf "%s\n" '  vhost-user-blk-server'
   printf "%s\n" '  build vhost-user-blk server'
-  printf "%s\n" '  vduse-blk-export'
-  printf "%s\n" '  VDUSE block export support'
   printf "%s\n" '  vhost-vdpa  vhost-vdpa kernel backend support'
   printf "%s\n" '  virglrenderer   virgl rendering support'
   printf "%s\n" '  virtfs  virtio-9p support'
@@ -283,6 +287,8 @@ _meson_option_parse() {
 --disable-guest-agent-msi) printf "%s" -Dguest_agent_msi=disabled ;;
 --enable-hax) printf "%s" -Dhax=enabled ;;
 --disable-hax) printf "%s" -Dhax=disabled ;;
+--enable-hexagon-idef-parser) printf "%s" -Dhexagon_idef_parser=true ;;
+--disable-hexagon-idef-parser) printf "%s" -Dhexagon_idef_parser=false ;;
 --enable-hvf) printf "%s" -Dhvf=enabled ;;
 --disable-hvf) printf "%s" -Dhvf=disabled ;;
 --iasl=*) quote_sh "-Diasl=$2" ;;
@@ -429,6 +435,8 @@ _meson_option_parse() {
 --disable-vde) printf "%s" -Dvde=disabled ;;
 --enable-vdi) printf "%s" -Dvdi=enabled ;;
 --disable-vdi) printf "%s" -Dvdi=disabled ;;
+--enable-vduse-blk-export) printf "%s" -Dvduse_blk_export=enabled ;;
+--disable-vduse-blk-export) printf "%s" -Dvduse_blk_export=disabled ;;
 --enable-vfio-user-server) printf "%s" -Dvfio_user_server=enabled ;;
 --disable-vfio-user-server) printf "%s" -Dvfio_user_server=disabled ;;
 --enable-vhost-crypto) printf "%s" -Dvhost_crypto=enabled ;;
@@ -441,8 +449,6 @@ _meson_option_parse() {
 --disable-vhost-user) printf "%s" -Dvhost_user=disabled ;;
 --enable-vhost-user-blk-server) printf "

Re: [PULL 17/21] target/hexagon: prepare input for the idef-parser

2022-12-31 Thread Alessandro Di Federico via
On Thu, 29 Dec 2022 11:41:22 +0100
Thomas Huth  wrote:

> I'm now seeing changes to scripts/meson-buildoptions.sh after
> rebuilding QEMU ... looks like you likely forgot to update that file
> with the automatic update after changing meson_options.txt ?

Ah, there seems to be another couple of unrelated missing updates to
scripts/meson-buildoptions.sh.

`Makefile` seems to rely on modification dates of files in the source
tree, but git does not track those.

git clone ...
mkdir build
./configure ...
make update-buildoptions # Does nothing
touch ../meson_options.txt
make update-buildoptions # Actually makes changes

Also, AFAIU the `update-buildoptions` target is not available in ninja.
However maybe this is not a bug since the doc says to use make.

Anyway, patch coming soon!

-- 
Alessandro Di Federico
rev.ng Labs



Re: [PATCH 1/1] target/hexagon: work around unused variable in yyparser

2022-12-31 Thread Alessandro Di Federico via
On Sat, 31 Dec 2022 17:19:35 +0800
Zongyuan Li  wrote:

> Variable 'yynerrs' is recognized as unused variable in clang15,

This issue is already handled by another similar patch (target/hexagon:
suppress unused variable warning) that will soon end up in a pull
request.

Thanks for looking into this though.

-- 
Alessandro Di Federico
rev.ng Labs



[RFC] Reducing NEED_CPU_H usage

2022-12-28 Thread Alessandro Di Federico via
Hello everyone, this is a proposal in the libtcg direction, i.e.,
enabling building a single QEMU executable featuring multiple *targets*
(i.e., TCG frontends).
This follows what we discussed in recent KVM calls and originally at
the KVM Forum Emulation BoF.

Note that our commitment to this project is possible thanks to our
collaboration with the Qualcomm Innovation Center!

# Grand goal

The following is the core point where translation of input code to host
code takes place:

TranslationBlock *tb_gen_code(CPUState *cpu,
  target_ulong pc, target_ulong cs_base,
  uint32_t flags, int cflags)
{
// ...

gen_intermediate_code(cpu, tb, max_insns, pc, host_pc);

// ...

gen_code_size = tcg_gen_code(tcg_ctx, tb, pc);

// ...
}

https://github.com/qemu/qemu/blob/4e4fa6c/accel/tcg/translate-all.c#L816

We want:

* `gen_intermediate_code` to be target-specific (provided by a shared
  library)
* `tb_gen_code` and `tcg_gen_code` to be target-agnostic

Result: the frontend just emits instructions into the
`TranslationBlock`, not much more.

But first we need to make sure that QEMU is neatly divided into
components that can make compile-time assumptions about the target and
components that don't, which is what this proposal is about.

This will be a large chunk of work affecting many parts of the code and
requiring some infrastructural changes.

# Strategy

The strategy to make this happen is primarily to have an out-of-tree
branch where the development of libtcg takes place. The main goal is to
be able to limit usage of `NEED_CPU_H` and some other macros only to
certain places (mainly `target/*` and `{bsd,linux}-user/*`).

Initially we will focus on getting a `--target-list=x86_64-linux-user`
configuration to build with reduced usage of `NEED_CPU_H`. This is just
for simplicity, we intend to tackle all other configurations
step-by-step.

At first, there will be lots of hacks to make it build and QEMU won't
be operational, but building it will enable us to identify all the core
issues.

Once all the core issues have been identified, we intend to prepare
fixes for each one of them and frequently send them upstream in a form
palatable for master. For instance, we expect to have a patch to move
from `TARGET_TB_PCREL` to `TranslationBlock.pc_rel`.

This way, we hope to be able to tackle the project in small bites and,
at a certain point, send a patch upstream where `NEED_CPU_H` is
actually disabled in many many places. Given the amount of work, doing
everything in a single shot does not seem feasible or beneficial.

# Core issues identifed so far

In the following we report some of the core issues we identified, why
they are problematic and what we intend to do to tackle them. Feedback
on each and every point is very welcome! :)

## `NEED_CPU_H`

`NEED_CPU_H` is a macro to decide whether a certain translation unit
needs `target/$ARCH/cpu.h` or not. In several headers, this macro is
used to guard target-specific code.

Problem: we need to build translation units out of the `target/`
and `*-user/` directories *without* this macro being defined.
This also means that many files will be compiled only once and not once
per target!

Solution: Fix all the issues caused by undefining it (main ones
are reported below). Sometimes a solution is to take headers that are
currently target-specific headers and introduce `#ifdef NEED_CPU_H` in
certain parts so that they become target-agnostic.

At a certain point it might make sense to count how many lines are
guarded by such macro and consider splitting headers into
target-agnostic and target-specific ones.

Note: currently, we plan to get rid of all usages of `TARGET_*`
macros in code that we want to become target agnostic but *not* of
`CONFIG_USER_ONLY` and `CONFIG_SOFTMMU`. At least initially, our goal
is just to decouple translation units out of `target/`/`*-user/` from
target-specific assumptions.

## `target_ulong`

`target_ulong` is `uint32_t` in 32-bit targets and `uint64_t` in 64-bit
targets.

Problem: This is used in many many places to represent addresses in
code that could become target-independent.

Proposed solution: we can convert it to:

typedef uint64_t target_address;

The problem with this is that, if arithmetic operations are performed
on it, we might get undesired results:

// Was: char load_data(target_ulong address)
char load_data(target_address address) {
  char *base_address = get_base_address();
  // On a 32-bits target this would overflow, it doesn't with
  // uint64_t
  target_address real_address = address + 1;
  return *(base_address + real_address);
}

load_data(UINT32_MAX);

This is might be a source of subtle bugs.
We're using a rough `clang-query` invocation to see who performs
arithmetic on `target_ulong`:

$ cd build
$ cat compile_commands.json \
| jq -r '.[] | .[

Re: [PATCH] target/hexagon/idef-parser: fix two typos in README

2022-12-28 Thread Alessandro Di Federico via
On Tue, 27 Dec 2022 17:49:04 -0300
Matheus Tavares Bernardino  wrote:

> Signed-off-by: Matheus Tavares Bernardino 
> ---
>  target/hexagon/idef-parser/README.rst | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Alessandro Di Federico 

Thanks for the fixes!

-- 
Alessandro Di Federico
rev.ng Labs



[PATCH v2] target/hexagon: suppress unused variable warning

2022-12-21 Thread Alessandro Di Federico via
This patch manually suppresses a warning for an unused variable
(yynerrs) emitted by bison.

This warning has been triggered for the first time by clang 15.

This patch also disables `-Wextra`, which is not usually adopted in
QEMU. However, clang 15 triggers the warning fixed in this patch even in
absence of `-Wextra`.

Signed-off-by: Alessandro Di Federico 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Taylor Simpson 
Tested-by: Taylor Simpson 
---
 target/hexagon/idef-parser/idef-parser.y | 2 ++
 target/hexagon/meson.build   | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/idef-parser/idef-parser.y 
b/target/hexagon/idef-parser/idef-parser.y
index 8be44a0ad17..c14cb395005 100644
--- a/target/hexagon/idef-parser/idef-parser.y
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -99,6 +99,8 @@
 /* Input file containing the description of each hexagon instruction */
 input : instructions
   {
+  /* Suppress warning about unused yynerrs */
+  (void) yynerrs;
   YYACCEPT;
   }
   ;
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index e8f250fcac5..c9d31d095ca 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -197,7 +197,6 @@ if idef_parser_enabled and 'hexagon-linux-user' in 
target_dirs
  idef_parser_dir / 'parser-helpers.c'],
 include_directories: ['idef-parser', '../../include/'],
 dependencies: [glib_dep],
-c_args: ['-Wextra'],
 native: true
 )
 
-- 
2.38.1




[PATCH] target/hexagon: suppress unused variable warning

2022-12-21 Thread Alessandro Di Federico via
This patch manually suppresses a warning for an unused variable
(yynerrs) emitted by bison.

This warning has been triggered for the first time by clang 15.

This patch also disables `-Wextra`, which is not usually adopted in
QEMU. However, clang 15 triggers the warning fixed in this patch even in
absence of `-Wextra`.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/idef-parser/idef-parser.y | 2 ++
 target/hexagon/meson.build   | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/idef-parser/idef-parser.y 
b/target/hexagon/idef-parser/idef-parser.y
index 8be44a0ad17..de61f48a628 100644
--- a/target/hexagon/idef-parser/idef-parser.y
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -99,6 +99,8 @@
 /* Input file containing the description of each hexagon instruction */
 input : instructions
   {
+  // Suppress warning about unused yynerrs
+  (void) yynerrs;
   YYACCEPT;
   }
   ;
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index e8f250fcac5..c9d31d095ca 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -197,7 +197,6 @@ if idef_parser_enabled and 'hexagon-linux-user' in 
target_dirs
  idef_parser_dir / 'parser-helpers.c'],
 include_directories: ['idef-parser', '../../include/'],
 dependencies: [glib_dep],
-c_args: ['-Wextra'],
 native: true
 )
 
-- 
2.38.1




Re: [PULL 00/21] Hexagon update: bug fixes, performance, idef-parser

2022-12-20 Thread Alessandro Di Federico via
On Tue, 20 Dec 2022 08:30:02 +0100
Philippe Mathieu-Daudé  wrote:

> Do we really need this level? IIUC the problem with -Wextra is using a
> newer compiler toolchain it can include warnings we haven't fixed.
> Maybe worthwhile but it can break from times to times.

I think we just wanted to be overly zealous.
Flags typically used by QEMU are fine.

Shall I send a patch to drop -Wextra?

-- 
Alessandro Di Federico
rev.ng Labs



Re: [PULL 00/21] Hexagon update: bug fixes, performance, idef-parser

2022-12-20 Thread Alessandro Di Federico via
On Mon, 19 Dec 2022 18:54:22 +
Taylor Simpson  wrote:

> > Applied, thanks.  
> 
> Thanks!!

Thanks from our side too! :)

We started this project back in 2015, I'm really happy we finally got
it in!

-- 
Alessandro Di Federico
rev.ng Labs



Re: Any interest in a QEMU emulation BoF at KVM Forum?

2022-09-01 Thread Alessandro Di Federico via
I'm very interested too. Thanks for organizing this, Alex!

In particular we're interested in the infrastructure work to enable
having a single build of QEMU using several different TCG frontends,
which is probably preliminary to heterogeneous vCPU emulation.

In fact, I was going to send an RFC about this to qemu-devel, but KVM
Forum + this BoF seemed like a good opportunity to discuss this. I
might share it later, if you're intersted.

Will the BoF pop up in the program or will it be something informal?
According to the schedule, there are BoFs Mon 17.40 and Tue 17.40.

Catch you in Dublin and thanks again for setting this up.

-- 
Alessandro Di Federico
rev.ng Labs



Re: [PATCH v6 0/7] tests: Refresh lcitool submodule & remove libxml2

2022-01-30 Thread Alessandro Di Federico via
On Tue, 25 Jan 2022 11:59:38 +0100
Philippe Mathieu-Daudé via  wrote:

> I'm seeing the same issue with these domains since mid december:
> 
> ...
> - rev.ng
> 
> ...
> https://lore.kernel.org/qemu-devel/20220105185720.0d4fc159@orange/
> ...

I've tried to look into this and it looks like our set up should be OK.
We enabled SPF (i.e., a rule stating that only our mailserver can send
e-mail with our domain in "From:") and DKIM (i.e., our mailserver signs
certain portions of the e-mail). We also enabled DMARC which
coordinates the two.

Now, as far as I understand, mailing lists can either rewrite the
"From" header (as qemu-devel does) or leave it as it is. In the latter
situation, SPF will fail but DMARC should instruct MTAs to check
DKIM, and that should pass.

https://begriffs.com/posts/2018-09-18-dmarc-mailing-list.html

https://dmarc.org/wiki/FAQ#I_operate_a_mailing_list_and_I_want_to_interoperate_with_DMARC.2C_what_should_I_do.3F

DKIM signature can be corrupted in case the mailing list tampers with
the subject or the body of the e-mail, but this doesn't seem to be the
case: I've tried to manually verify the DKIM signature of the same
e-mail that I got both from the mailing list and directly from the
sender (I was in Cc), and they both verify correctly.

tl;dr I *think* rewriting the From header should not be necessary for
our domain.

If you guys think this is not the case and there's something we can do
to improve the situation (other than adding gmail.com to our SPF
record), let me know.

-- 
Alessandro Di Federico
rev.ng Labs



CI for qemu-hexagon

2022-01-05 Thread Alessandro Di Federico via
Hi Alex, I hope you enjoyed the holidays!

We're trying to upstream idef-parser (the automatic generator of the
Hexagon frontend). This introduces new dependencies, specifically flex
and bison.

Attached you can find our patch for that.

However the CI fails:

https://gitlab.com/carl.cudig/qemu/-/jobs/1939950230

AFAIU the Hexagon docker image is "special" since it's the only one
that needs the cross-compiler to be built from source and, therefore,
it's a process that needs to be triggered manually.
Is this correct?

If so, what should we do? Make a pull request despite the failure and
then it will be taken care of, or should I make a separate (preliminary)
pull request just for that patch?

-- 
Alessandro Di Federico
rev.ng
commit 14e90d55b368b4a56fde668b66311bab6e1a4518
Author: Paolo Montesel 
Date:   Thu Dec 9 13:23:06 2021 +0100

target/hexagon: import flex/bison to docker files

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 

diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml
index 309f7e7fb86..2abfe4e91aa 100644
--- a/.gitlab-ci.d/windows.yml
+++ b/.gitlab-ci.d/windows.yml
@@ -33,6 +33,7 @@ msys2-64bit:
   script:
   - .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
   diffutils git grep make sed
+  flex bison
   mingw-w64-x86_64-capstone
   mingw-w64-x86_64-curl
   mingw-w64-x86_64-cyrus-sasl
@@ -68,6 +69,7 @@ msys2-32bit:
   script:
   - .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
   diffutils git grep make sed
+  flex bison
   mingw-w64-i686-capstone
   mingw-w64-i686-curl
   mingw-w64-i686-cyrus-sasl
diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker
index 7e6997e3015..45db55ba55a 100644
--- a/tests/docker/dockerfiles/alpine.docker
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -9,9 +9,11 @@ ENV PACKAGES \
 	alsa-lib-dev \
 	bash \
 	binutils \
+	bison \
 	ccache \
 	coreutils \
 	curl-dev \
+	flex \
 	g++ \
 	gcc \
 	git \
diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker
index 7f135f8e8c0..d93bbe30026 100644
--- a/tests/docker/dockerfiles/centos8.docker
+++ b/tests/docker/dockerfiles/centos8.docker
@@ -5,6 +5,7 @@ ENV PACKAGES \
 SDL2-devel \
 alsa-lib-devel \
 bc \
+bison \
 brlapi-devel \
 bzip2 \
 bzip2-devel \
@@ -19,6 +20,7 @@ ENV PACKAGES \
 device-mapper-multipath-devel \
 diffutils \
 findutils \
+flex \
 gcc \
 gcc-c++ \
 genisoimage \
diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker
index ed546edcd65..805fd6f981d 100644
--- a/tests/docker/dockerfiles/debian-amd64.docker
+++ b/tests/docker/dockerfiles/debian-amd64.docker
@@ -14,9 +14,11 @@ RUN apt update && \
 RUN apt update && \
 DEBIAN_FRONTEND=noninteractive eatmydata \
 apt install -y --no-install-recommends \
+bison \
 cscope \
 genisoimage \
 exuberant-ctags \
+flex \
 global \
 libbz2-dev \
 liblzo2-dev \
diff --git a/tests/docker/dockerfiles/debian-native.docker b/tests/docker/dockerfiles/debian-native.docker
index efd55cb6e0e..02ccaf98fd1 100644
--- a/tests/docker/dockerfiles/debian-native.docker
+++ b/tests/docker/dockerfiles/debian-native.docker
@@ -26,13 +26,16 @@ RUN apt update && \
 RUN apt update && \
 DEBIAN_FRONTEND=noninteractive eatmydata \
 apt install -y --no-install-recommends \
+bison \
 cscope \
 genisoimage \
 exuberant-ctags \
+flex \
 global \
 libbz2-dev \
 liblzo2-dev \
 libgcrypt20-dev \
+libglib2.0-dev \
 libfdt-dev \
 librdmacm-dev \
 libsasl2-dev \
diff --git a/tests/docker/dockerfiles/debian-riscv64-cross.docker b/tests/docker/dockerfiles/debian-riscv64-cross.docker
index 594d97982c1..f5553afc2e1 100644
--- a/tests/docker/dockerfiles/debian-riscv64-cross.docker
+++ b/tests/docker/dockerfiles/debian-riscv64-cross.docker
@@ -17,12 +17,15 @@ RUN apt update && \
 # Install common build utilities
 RUN DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy \
 bc \
+bison \
 build-essential \
 ca-certificates \
 debian-ports-archive-keyring \
 dpkg-dev \
+flex \
 gettext \
 git \
+libglib2.0-dev \
 ninja-build \
 pkg-config \
 python3
diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker b/tests/docker/dockerfiles/debian-tricore-cross.docker
index d8df2c61170..9191aafc7f3 100644
--- a/tests/docker/dockerfiles/debian-tricore-cross.docker
+++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
@@ -16,9 +16,11 @@ MAINTAINER Philippe Mathieu-Daudé 
 RUN apt update && \
 DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
 DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy \
+   bison 

Re: QEMU CI failure of cross-i386-* targets (meson picks wrong glib for native target)

2021-12-29 Thread Alessandro Di Federico via
On Fri, 24 Dec 2021 22:25:24 +0100
Paolo Bonzini  wrote:

> Is the configure script setting $cross_compile to yes? That will
> decide whether meson getting a --cross-file or a --native-file
> option, and consequently whether it treats the host and build
> machines as equal or different.

From what I can see cross_compile is set only if --cross-prefix is set,
which doesn't seem to be the case for most containers (e.g., s390x)
but not for i386:

tests/docker/dockerfiles/debian-s390x-cross.docker:ENV QEMU_CONFIGURE_OPTS 
--cross-prefix=s390x-linux-gnu-
tests/docker/dockerfiles/fedora-i386-cross.docker:ENV QEMU_CONFIGURE_OPTS 
--cpu=i386 --disable-vhost-user

I can try to set `--cross-prefix=x86_64-redhat-linux-` but I guess this
will prevent certain tests to run (given the cross-compile environment).

I'll give it a shot.

-- 
Alessandro Di Federico
rev.ng Labs Srl



QEMU CI failure of cross-i386-* targets (meson picks wrong glib for native target)

2021-12-24 Thread Alessandro Di Federico via
Hi Paolo, I'm trying to get the QEMU CI run successfully for the
idef-parser patchset. However I'm facing an issue I haven't been able
to work around with meson. Maybe you can help?

The failing tests are cross-i386-*

https://gitlab.com/carl.cudig/qemu/-/jobs/1437392669
https://gitlab.com/carl.cudig/qemu/-/jobs/1437392673
https://gitlab.com/carl.cudig/qemu/-/jobs/1437392671

I think the problem is that we're adding a new build-time dependency:
glib. However glib is also a run-time dependency and, AFAIU, when cross
compiling for x86 on a x86-64 machine, if you create a native
executable, meson picks up the x86 version of glib (as opposed to the
x86-64).

I've been fiddling with this for a while, unsuccessfully.

Relevant portion of the code:


https://gitlab.com/carl.cudig/qemu/-/commit/c020958c37fa723f7e933a58b1bb1c3668ff4cff#8145a41027f26ff426d5a2c8b00c56f227943165_198_202

Happy holidays!

-- 
Alessandro Di Federico
rev.ng Labs Srl



[PATCH v6 12/12] gitlab-ci: do not use qemu-project Docker registry

2021-07-20 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This commit is necessary in order to use container built by the current
run of the CI. If we don't do this, we use official containers which are
not affected by the additional dependencies we're introducing.

This should be considered as a temporary solution in order to test this
patchset.

Signed-off-by: Alessandro Di Federico 
---
 .gitlab-ci.d/container-cross.yml| 2 +-
 .gitlab-ci.d/container-template.yml | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.gitlab-ci.d/container-cross.yml b/.gitlab-ci.d/container-cross.yml
index 0fcebe363a..eb134e927d 100644
--- a/.gitlab-ci.d/container-cross.yml
+++ b/.gitlab-ci.d/container-cross.yml
@@ -63,7 +63,7 @@ hexagon-cross-container:
 - docker:dind
   before_script:
 - export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
-- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest"
+- export COMMON_TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
 - docker info
 - docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p 
"$CI_REGISTRY_PASSWORD"
   script:
diff --git a/.gitlab-ci.d/container-template.yml 
b/.gitlab-ci.d/container-template.yml
index 1baecd9460..c85ae377b8 100644
--- a/.gitlab-ci.d/container-template.yml
+++ b/.gitlab-ci.d/container-template.yml
@@ -5,7 +5,7 @@
 - docker:dind
   before_script:
 - export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
-- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/$NAME:latest"
+- export COMMON_TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
 - apk add python3
 - docker info
 - docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p 
"$CI_REGISTRY_PASSWORD"
@@ -14,7 +14,7 @@
 - echo "COMMON_TAG:$COMMON_TAG"
 - ./tests/docker/docker.py --engine docker build
   -t "qemu/$NAME" -f "tests/docker/dockerfiles/$NAME.docker"
-  -r $CI_REGISTRY/qemu-project/qemu
+  -r $CI_REGISTRY_IMAGE
 - docker tag "qemu/$NAME" "$TAG"
 - docker push "$TAG"
   after_script:
-- 
2.32.0




[PATCH v6 08/12] target/hexagon: import lexer for idef-parser

2021-07-20 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.h  | 258 +++
 target/hexagon/idef-parser/idef-parser.lex| 642 ++
 target/hexagon/meson.build|   4 +
 tests/docker/dockerfiles/alpine.docker|   1 +
 tests/docker/dockerfiles/centos8.docker   |   1 +
 tests/docker/dockerfiles/debian-amd64.docker  |   1 +
 tests/docker/dockerfiles/debian10.docker  |   1 +
 .../dockerfiles/fedora-i386-cross.docker  |   1 +
 .../dockerfiles/fedora-win32-cross.docker |   1 +
 .../dockerfiles/fedora-win64-cross.docker |   1 +
 tests/docker/dockerfiles/fedora.docker|   1 +
 tests/docker/dockerfiles/opensuse-leap.docker |   1 +
 tests/docker/dockerfiles/ubuntu.docker|   1 +
 tests/docker/dockerfiles/ubuntu1804.docker|   1 +
 tests/docker/dockerfiles/ubuntu2004.docker|   2 +
 15 files changed, 917 insertions(+)
 create mode 100644 target/hexagon/idef-parser/idef-parser.h
 create mode 100644 target/hexagon/idef-parser/idef-parser.lex

diff --git a/target/hexagon/idef-parser/idef-parser.h 
b/target/hexagon/idef-parser/idef-parser.h
new file mode 100644
index 00..f2c07793c6
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef IDEF_PARSER_H
+#define IDEF_PARSER_H
+
+#include 
+#include 
+#include 
+#include 
+
+#define TCGV_NAME_SIZE 7
+#define MAX_WRITTEN_REGS 32
+#define OFFSET_STR_LEN 32
+#define ALLOC_LIST_LEN 32
+#define ALLOC_NAME_SIZE 32
+#define INIT_LIST_LEN 32
+#define OUT_BUF_LEN (1024 * 1024)
+#define SIGNATURE_BUF_LEN (128 * 1024)
+#define HEADER_BUF_LEN (128 * 1024)
+
+/* Variadic macros to wrap the buffer printing functions */
+#define EMIT(c, ...) \
+do { \
+g_string_append_printf((c)->out_str, __VA_ARGS__);   \
+} while (0)
+
+#define EMIT_SIG(c, ...)   
\
+do {   
\
+g_string_append_printf((c)->signature_str, __VA_ARGS__);   
\
+} while (0)
+
+#define EMIT_HEAD(c, ...)  
\
+do {   
\
+g_string_append_printf((c)->header_str, __VA_ARGS__);  
\
+} while (0)
+
+/**
+ * Type of register, assigned to the HexReg.type field
+ */
+typedef enum {GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW} RegType;
+
+typedef enum { UNKNOWN_SIGNEDNESS, SIGNED, UNSIGNED } HexSignedness;
+
+/**
+ * Semantic record of the REG tokens, identifying registers
+ */
+typedef struct HexReg {
+uint8_t id; /**< Identifier of the register  */
+RegType type;   /**< Type of the register*/
+unsigned bit_width; /**< Bit width of the reg, 32 or 64 bits */
+} HexReg;
+
+/**
+ * Data structure, identifying a TCGv temporary value
+ */
+typedef struct HexTmp {
+int index;  /**< Index of the TCGv temporary value*/
+} HexTmp;
+
+/**
+ * Enum of the possible immediated, an immediate is a value which is known
+ * at tinycode generation time, e.g. an integer value, not a TCGv
+ */
+enum ImmUnionTag {
+I,
+VARIABLE,
+VALUE,
+QEMU_TMP,
+IMM_PC,
+IMM_NPC,
+IMM_CONSTEXT,
+};
+
+/**
+ * Semantic record of the IMM token, identifying an immediate constant
+ */
+typedef struct HexImm {
+union {
+char id;/**< Identifier of the immediate */
+uint64_t value; /**< Immediate value (for VALUE type immediates) */
+uint64_t index; /**< Index of the immediate (for int temp vars)  */
+};
+enum ImmUnionTag type;  /**< Type of the immediate  */
+} HexImm;
+
+/**
+ * Semantic record of the PRE token, identifying a predicate
+ */
+typedef struct HexPre {
+char id;/**< Identifier of the predicate */
+} HexPre;
+
+/**
+ * Semantic record of the SAT token, ident

[PATCH v6 00/12] target/hexagon: introduce idef-parser

2021-07-20 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This patchset introduces the idef-parser for target/hexagon.

It's the sixth iteration of the patchset and includes fixes suggested in
previous iterations.

`idef-parser` is a build-time tool built using flex and bison. Its aim
is to generate a large part of the tiny code generator frontend for
Hexagon. The prototype of idef-parser has been presented at KVM Forum
2019 ("QEMU-Hexagon: Automatic Translation of the ISA Manual Pseudcode
to Tiny Code Instructions"):

https://www.youtube.com/watch?v=3EpnTYBOXCI

`target/hexagon/idef-parser/README.rst` provides an overview of the
parser and its inner working.

A couple of notes:

* Among other things, this commit ensures the signedness is always
  properly propagated and that memory safety tools (valgrind and various
  sanitizers) report no issues on the parser.
* We now also indent the generated C code using `indent`, if availble.
  This has no run-time effect, it's just to ease debugging.
* These commits build successfully on the CI (including using clang),
  with some exceptions.
  The build on the CI fails for the cross-i386-* jobs. This seems to be
  due to the fact that, despite we specified glib as a native
  dependency, meson still chooses the i386 bit version of the library,
  as opposed to the x86-64.
  We also introduced a commit to make sure containers produced by the
  developer Docker registry (as opposed to the official one) is
  used. Otherwise, the changes we made to the containers would not
  take effect.
  However, as Daniel pointed out, our solution is an hack.
  Since this is a problem only for developers when introducing new
  dependencies for the containers, we might consider not merging the
  last patch at all. But it's required in order to get some success in
  testing on the CI it required.
  Also, building debian-hexagon-cross still fails since it's not built
  by the CI by default.
  Help on these matters is appreciated.

Alessandro Di Federico (5):
  target/hexagon: update MAINTAINERS for idef-parser
  target/hexagon: import README for idef-parser
  target/hexagon: prepare input for the idef-parser
  target/hexagon: call idef-parser functions
  gitlab-ci: do not use qemu-project Docker registry

Niccolò Izzo (2):
  target/hexagon: introduce new helper functions
  target/hexagon: import additional tests

Paolo Montesel (5):
  target/hexagon: make slot number an unsigned
  target/hexagon: make helper functions non-static
  target/hexagon: expose next PC in DisasContext
  target/hexagon: import lexer for idef-parser
  target/hexagon: import parser for idef-parser

 target/hexagon/idef-parser/README.rst |  447 +++
 target/hexagon/genptr.h   |   43 +
 target/hexagon/idef-parser/idef-parser.h  |  258 ++
 target/hexagon/idef-parser/parser-helpers.h   |  346 +++
 target/hexagon/macros.h   |   11 +-
 target/hexagon/op_helper.h|   37 +
 target/hexagon/translate.h|1 +
 target/hexagon/genptr.c   |  176 +-
 target/hexagon/idef-parser/parser-helpers.c   | 2396 +
 target/hexagon/op_helper.c|   29 +-
 target/hexagon/translate.c|3 +-
 .gitlab-ci.d/container-cross.yml  |2 +-
 .gitlab-ci.d/container-template.yml   |4 +-
 MAINTAINERS   |8 +
 target/hexagon/README |5 +
 target/hexagon/gen_helper_funcs.py|5 +-
 target/hexagon/gen_helper_protos.py   |5 +-
 target/hexagon/gen_idef_parser_funcs.py   |  114 +
 target/hexagon/gen_tcg_funcs.py   |   28 +-
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/idef-parser.lex|  642 +
 target/hexagon/idef-parser/idef-parser.y  |  975 +++
 target/hexagon/idef-parser/macros.inc |  153 ++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/meson.build|  126 +-
 tests/docker/dockerfiles/alpine.docker|2 +
 tests/docker/dockerfiles/centos8.docker   |2 +
 tests/docker/dockerfiles/debian-amd64.docker  |2 +
 tests/docker/dockerfiles/debian10.docker  |3 +
 .../dockerfiles/fedora-i386-cross.docker  |3 +
 .../dockerfiles/fedora-win32-cross.docker |3 +
 .../dockerfiles/fedora-win64-cross.docker |3 +
 tests/docker/dockerfiles/fedora.docker|2 +
 tests/docker/dockerfiles/opensuse-leap.docker |2 +
 tests/docker/dockerfiles/ubuntu.docker|3 +
 tests/docker/dockerfiles/ubuntu1804.docker|2 +
 tests/docker/dockerfiles/ubuntu2004.docker|2 +
 tests/tcg/hexagon/Makefile.target |   30 +-
 tests/tcg/hexagon/crt.S   |   26 +
 tests/tcg/hexagon/test_abs.S  |   20 +
 tests/tcg/hexagon/test_bitcnt.S   |   42 +
 tests/tcg/hexagon/test_bitsplit.S

[PATCH v6 07/12] target/hexagon: prepare input for the idef-parser

2021-07-20 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Introduce infrastructure necessary to produce a file suitable for being
parsed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_idef_parser_funcs.py | 114 ++
 target/hexagon/idef-parser/macros.inc   | 153 
 target/hexagon/idef-parser/prepare  |  24 
 target/hexagon/meson.build  |  16 +++
 4 files changed, 307 insertions(+)
 create mode 100644 target/hexagon/gen_idef_parser_funcs.py
 create mode 100644 target/hexagon/idef-parser/macros.inc
 create mode 100755 target/hexagon/idef-parser/prepare

diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
new file mode 100644
index 00..7b8e0f6981
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+##
+##  This program 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.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, see .
+##
+
+import sys
+import re
+import string
+from io import StringIO
+
+import hex_common
+
+##
+## Generate code to be fed to the idef_parser
+##
+## Consider A2_add:
+##
+## Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
+##
+## We produce:
+##
+## A2_add(RdV, in RsV, in RtV) {
+##   { RdV=RsV+RtV;}
+## }
+##
+## A2_add represents the instruction tag. Then we have a list of TCGv
+## that the code generated by the parser can expect in input. Some of
+## them are inputs ("in" prefix), while some others are outputs.
+##
+def main():
+hex_common.read_semantics_file(sys.argv[1])
+hex_common.read_attribs_file(sys.argv[2])
+hex_common.read_overrides_file(sys.argv[3])
+hex_common.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[4], 'w') as f:
+f.write('#include "macros.inc"\n\n')
+
+for tag in hex_common.tags:
+## Skip the priv instructions
+if ( "A_PRIV" in hex_common.attribdict[tag] ) :
+continue
+## Skip the guest instructions
+if ( "A_GUEST" in hex_common.attribdict[tag] ) :
+continue
+## Skip instructions using switch
+if ( tag in {'S4_vrcrotate_acc', 'S4_vrcrotate'} ) :
+continue
+## Skip trap instructions
+if ( tag in {'J2_trap0', 'J2_trap1'} ) :
+continue
+## Skip 128-bit instructions
+if ( tag in {'A7_croundd_ri', 'A7_croundd_rr'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag.startswith('S2_cabacdecbin') ) :
+continue
+if ( tag.startswith('Y') ) :
+continue
+if ( tag.startswith('V6_') ) :
+continue
+if ( tag.startswith('F') ) :
+continue
+if ( tag.endswith('_locked') ) :
+continue
+
+regs = tagregs[tag]
+imms = tagimms[tag]
+
+arguments = []
+if hex_common.need_ea(tag):
+arguments.append("EA")
+
+for regtype,regid,toss,numregs in regs:
+prefix = "in " if hex_common.is_read(regid) else ""
+
+is_pair = hex_common.is_pair(regid)
+is_single_old = (hex_common.is_single(regid)
+ and hex_common.is_old_val(regtype, regid, 
tag))
+is_single_new = (hex_common.is_single(regid)
+ and hex_common.is_new_val(regtype, regid, 
tag))
+
+if is_pair or is_single_old:
+arguments.append("%s%s%sV" % (prefix, regtype, regid))
+elif is_single_new:
+arguments.append("%s%s%sN" % (prefix, regtype, regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+for immlett,bits,immshift in imms:
+arguments.append(hex_common.imm_name(immlett))
+
+f.write("%s(%s) {\n" % (tag, ", ".join(arguments)))
+f.write("%s\n" % hex_common.semdict[tag])
+f.write("}\n\n")
+
+if __name__ == "__main__":
+main()
diff --git a/target/hexagon/idef-parser/macros.inc 
b/target/hexagon/idef-parser/macros.inc
new

[PATCH v6 10/12] target/hexagon: call idef-parser functions

2021-07-20 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Extend gen_tcg_funcs.py in order to emit calls to the functions emitted
by the idef-parser, if available.

Signed-off-by: Alessandro Di Federico 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/gen_helper_funcs.py  |  5 +-
 target/hexagon/gen_helper_protos.py |  5 +-
 target/hexagon/gen_tcg_funcs.py | 28 +-
 target/hexagon/hex_common.py| 10 
 target/hexagon/meson.build  | 81 ++---
 5 files changed, 95 insertions(+), 34 deletions(-)

diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index 2b1c5d8e3e..40fcc0269a 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -192,11 +192,12 @@ def main():
 hex_common.read_semantics_file(sys.argv[1])
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -213,6 +214,8 @@ def main():
 continue
 if ( hex_common.skip_qemu_helper(tag) ):
 continue
+if ( hex_common.is_idef_parser_enabled(tag) ):
+continue
 
 gen_helper_function(f, tag, tagregs, tagimms)
 
diff --git a/target/hexagon/gen_helper_protos.py 
b/target/hexagon/gen_helper_protos.py
index ea41007ec9..6aee7229cb 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -121,11 +121,12 @@ def main():
 hex_common.read_semantics_file(sys.argv[1])
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -143,6 +144,8 @@ def main():
 
 if ( hex_common.skip_qemu_helper(tag) ):
 continue
+if ( hex_common.is_idef_parser_enabled(tag) ):
+continue
 
 gen_helper_prototype(f, tag, tagregs, tagimms)
 
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 7ceb25b5f6..e12f6b7cfc 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -394,7 +394,29 @@ def gen_tcg_func(f, tag, regs, imms):
 if (hex_common.is_read(regid)):
 genptr_src_read_opn(f,regtype,regid,tag)
 
-if ( hex_common.skip_qemu_helper(tag) ):
+if hex_common.is_idef_parser_enabled(tag):
+declared = []
+## Handle registers
+for regtype,regid,toss,numregs in regs:
+if (hex_common.is_pair(regid)
+or (hex_common.is_single(regid)
+and hex_common.is_old_val(regtype, regid, tag))):
+declared.append("%s%sV" % (regtype, regid))
+if regtype == "M":
+declared.append("%s%sN" % (regtype, regid))
+elif hex_common.is_new_val(regtype, regid, tag):
+declared.append("%s%sN" % (regtype,regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+## Handle immediates
+for immlett,bits,immshift in imms:
+declared.append(hex_common.imm_name(immlett))
+
+arguments = ", ".join(["ctx", "insn", "pkt"] + declared)
+f.write("emit_%s(%s);\n" % (tag, arguments))
+
+elif ( hex_common.skip_qemu_helper(tag) ):
 f.write("fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
 else:
 ## Generate the call to the helper
@@ -455,12 +477,14 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.calculate_attribs()
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
 f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
+f.write("#include \"idef-generated-emitter.h.inc\"\n\n")
 
 for tag in hex_common.tags:
 ## Skip the priv instructions
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index b3b534057d..648ad29e94 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -28,6 +28,7 @@
 attr

[PATCH v6 02/12] target/hexagon: import README for idef-parser

2021-07-20 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/idef-parser/README.rst | 447 ++
 target/hexagon/README |   5 +
 2 files changed, 452 insertions(+)
 create mode 100644 target/hexagon/idef-parser/README.rst

diff --git a/target/hexagon/idef-parser/README.rst 
b/target/hexagon/idef-parser/README.rst
new file mode 100644
index 00..9f20bce36a
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,447 @@
+Hexagon ISA instruction definitions to tinycode generator compiler
+--
+
+idef-parser is a small compiler able to translate the Hexagon ISA description
+language into tinycode generator code, that can be easily integrated into QEMU.
+
+Compilation Example
+---
+
+To better understand the scope of the idef-parser, we'll explore an applicative
+example. Let's start by one of the simplest Hexagon instruction: the ``add``.
+
+The ISA description language represents the ``add`` instruction as
+follows:
+
+.. code:: c
+
+   A2_add(RdV, in RsV, in RtV) {
+   { RdV=RsV+RtV;}
+   }
+
+idef-parser will compile the above code into the following code:
+
+.. code:: c
+
+   /* A2_add */
+   void emit_A2_add(DisasContext *ctx, Insn *insn, Packet *pkt, TCGv_i32 RdV,
+TCGv_i32 RsV, TCGv_i32 RtV)
+   /*  { RdV=RsV+RtV;} */
+   {
+   tcg_gen_movi_i32(RdV, 0);
+   TCGv_i32 tmp_0 = tcg_temp_new_i32();
+   tcg_gen_add_i32(tmp_0, RsV, RtV);
+   tcg_gen_mov_i32(RdV, tmp_0);
+   tcg_temp_free_i32(tmp_0);
+   }
+
+The output of the compilation process will be a function, containing the
+tinycode generator code, implementing the correct semantics. That function will
+not access any global variable, because all the accessed data structures will 
be
+passed explicitly as function parameters. Among the passed parameters we will
+have TCGv (tinycode variables) representing the input and output registers of
+the architecture, integers representing the immediates that come from the code,
+and other data structures which hold information about the disassemblation
+context (``DisasContext`` struct).
+
+Let's begin by describing the input code. The ``add`` instruction is associated
+with a unique identifier, in this case ``A2_add``, which allows to distinguish
+variants of the same instruction, and expresses the class to which the
+instruction belongs, in this case ``A2`` corresponds to the Hexagon
+``ALU32/ALU`` instruction subclass.
+
+After the instruction identifier, we have a series of parameters that 
represents
+TCG variables that will be passed to the generated function. Parameters marked
+with ``in`` are already initialized, while the others are output parameters.
+
+We will leverage this information to infer several information:
+
+-  Fill in the output function signature with the correct TCGv registers
+-  Fill in the output function signature with the immediate integers
+-  Keep track of which registers, among the declared one, have been
+   initialized
+
+Let's now observe the actual instruction description code, in this case:
+
+.. code:: c
+
+   { RdV=RsV+RtV;}
+
+This code is composed by a subset of the C syntax, and is the result of the
+application of some macro definitions contained in the ``macros.h`` file.
+
+This file is used to reduce the complexity of the input language where complex
+variants of similar constructs can be mapped to a unique primitive, so that the
+idef-parser has to handle a lower number of computation primitives.
+
+As you may notice, the description code modifies the registers which have been
+declared by the declaration statements. In this case all the three registers
+will be declared, ``RsV`` and ``RtV`` will also be read and ``RdV`` will be
+written.
+
+Now let's have a quick look at the generated code, line by line.
+
+::
+
+   tcg_gen_movi_i32(RdV, 0);
+
+This code starts by zero-initializing ``RdV``, since reading from that register
+without initialization will cause a segmentation fault by QEMU.  This is 
emitted
+since a declaration of the ``RdV`` register was parsed, but we got no 
indication
+that the variable has been initialized by the caller.
+
+::
+
+   TCGv_i32 tmp_0 = tcg_temp_new_i32();
+
+Then we are declaring a temporary TCGv to hold the result from the sum
+operation.
+
+::
+
+   tcg_gen_add_i32(tmp_0, RsV, RtV);
+
+Now we are actually generating the sum tinycode operator between the selected
+registers, storing the result in the just declared temporary.
+
+::
+
+   tcg_gen_mov_i32(RdV, tmp_0);
+
+The result of the addition is now stored in the temporary, we move it into the
+correct destination register. This might not seem an efficient code, but QEMU
+will perform some tinycode optimization, reducing the unnecessary copy.
+
+::
+
+   tcg_temp_free_i32(tmp_0);
+
+Finally, we free the temporary we used to hold the addition result.
+
+Parser Structure
+

[PATCH v6 09/12] target/hexagon: import parser for idef-parser

2021-07-20 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/parser-helpers.h   |  346 +++
 target/hexagon/idef-parser/parser-helpers.c   | 2396 +
 target/hexagon/idef-parser/idef-parser.y  |  975 +++
 target/hexagon/meson.build|   27 +-
 tests/docker/dockerfiles/alpine.docker|1 +
 tests/docker/dockerfiles/centos8.docker   |1 +
 tests/docker/dockerfiles/debian-amd64.docker  |1 +
 tests/docker/dockerfiles/debian10.docker  |2 +
 .../dockerfiles/fedora-i386-cross.docker  |2 +
 .../dockerfiles/fedora-win32-cross.docker |2 +
 .../dockerfiles/fedora-win64-cross.docker |2 +
 tests/docker/dockerfiles/fedora.docker|1 +
 tests/docker/dockerfiles/opensuse-leap.docker |1 +
 tests/docker/dockerfiles/ubuntu.docker|2 +
 tests/docker/dockerfiles/ubuntu1804.docker|1 +
 15 files changed, 3759 insertions(+), 1 deletion(-)
 create mode 100644 target/hexagon/idef-parser/parser-helpers.h
 create mode 100644 target/hexagon/idef-parser/parser-helpers.c
 create mode 100644 target/hexagon/idef-parser/idef-parser.y

diff --git a/target/hexagon/idef-parser/parser-helpers.h 
b/target/hexagon/idef-parser/parser-helpers.h
new file mode 100644
index 00..2d1fc5ab07
--- /dev/null
+++ b/target/hexagon/idef-parser/parser-helpers.h
@@ -0,0 +1,346 @@
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef PARSER_HELPERS_H
+#define PARSER_HELPERS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcg/tcg-cond.h"
+
+#include "idef-parser.tab.h"
+#include "idef-parser.yy.h"
+#include "idef-parser.h"
+
+/* Decomment this to disable yyasserts */
+/* #define NDEBUG */
+
+#define ERR_LINE_CONTEXT 40
+
+#define START_COMMENT "/" "*"
+#define END_COMMENT "*" "/"
+
+void yyerror(YYLTYPE *locp,
+ yyscan_t scanner __attribute__((unused)),
+ Context *c,
+ const char *s);
+
+#ifndef NDEBUG
+#define yyassert(context, locp, condition, msg) \
+if (!(condition)) { \
+yyerror(locp, (context)->scanner, (context), (msg)); \
+}
+#endif
+
+bool is_direct_predicate(HexValue *value);
+
+/* Print functions */
+void str_print(Context *c, YYLTYPE *locp, const char *string);
+
+void uint8_print(Context *c, YYLTYPE *locp, uint8_t *num);
+
+void uint64_print(Context *c, YYLTYPE *locp, uint64_t *num);
+
+void int_print(Context *c, YYLTYPE *locp, int *num);
+
+void uint_print(Context *c, YYLTYPE *locp, unsigned *num);
+
+void tmp_print(Context *c, YYLTYPE *locp, HexTmp *tmp);
+
+void pre_print(Context *c, YYLTYPE *locp, HexPre *pre, bool is_dotnew);
+
+void reg_compose(Context *c, YYLTYPE *locp, HexReg *reg, char reg_id[5]);
+
+void reg_print(Context *c, YYLTYPE *locp, HexReg *reg);
+
+void imm_print(Context *c, YYLTYPE *locp, HexImm *imm);
+
+void var_print(Context *c, YYLTYPE *locp, HexVar *var);
+
+void rvalue_out(Context *c, YYLTYPE *locp, void *pointer);
+
+void out_assert(Context *c, YYLTYPE *locp, void *dummy);
+
+/* Copy output code buffer into stdout */
+void commit(Context *c);
+
+#define OUT_IMPL(c, locp, x)\
+_Generic(*x,\
+char:  str_print,   \
+uint8_t:   uint8_print, \
+uint64_t:  uint64_print,\
+int:   int_print,   \
+unsigned:  uint_print,  \
+HexValue:  rvalue_out,  \
+default:   out_assert   \
+)(c, locp, x);
+
+/* Make a FOREACH macro */
+#define FE_1(c, locp, WHAT, X) WHAT(c, locp, X)
+#define FE_2(c, locp, WHAT, X, ...) \
+WHAT(c, locp, X)FE_1(c, locp, WHAT, __VA_ARGS__)
+#define FE_3(c, locp, WHAT, X, ...) \
+WHAT(c, locp, X)FE_2(c, locp, WHAT, __VA_ARGS__)
+#define FE_4(c, locp, WHAT, X, ...) \
+WHAT(c, locp, X)FE_3(c, locp, WHAT, __VA_ARGS__)
+#define FE_5(c, locp, WHAT, X, ...) \
+WHAT(c, locp, X)FE_4(c, locp, WHAT, __VA_ARGS__)
+#define FE_6(c, locp, WHAT, X, ...) \
+WHAT(c, locp, X)FE_5(c, locp, WHAT, __VA_ARGS__)
+#define FE_7(c, locp, WHAT, X, ...) \
+WHAT(c, locp, X)FE_6(c, locp

[PATCH v6 11/12] target/hexagon: import additional tests

2021-07-20 Thread Alessandro Di Federico via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 tests/tcg/hexagon/Makefile.target  | 30 +-
 tests/tcg/hexagon/crt.S| 26 
 tests/tcg/hexagon/test_abs.S   | 20 ++
 tests/tcg/hexagon/test_bitcnt.S| 42 
 tests/tcg/hexagon/test_bitsplit.S  | 25 
 tests/tcg/hexagon/test_call.S  | 60 
 tests/tcg/hexagon/test_clobber.S   | 35 +
 tests/tcg/hexagon/test_cmp.S   | 34 
 tests/tcg/hexagon/test_cmpy.S  | 31 +++
 tests/tcg/hexagon/test_dotnew.S| 36 +
 tests/tcg/hexagon/test_ext.S   | 16 
 tests/tcg/hexagon/test_fibonacci.S | 33 
 tests/tcg/hexagon/test_hl.S| 19 +
 tests/tcg/hexagon/test_hwloops.S   | 22 +++
 tests/tcg/hexagon/test_jmp.S   | 25 
 tests/tcg/hexagon/test_lsr.S   | 39 ++
 tests/tcg/hexagon/test_mpyi.S  | 20 ++
 tests/tcg/hexagon/test_overflow.S  | 63 ++
 tests/tcg/hexagon/test_packet.S| 26 
 tests/tcg/hexagon/test_reorder.S   | 29 ++
 tests/tcg/hexagon/test_round.S | 31 +++
 tests/tcg/hexagon/test_vavgw.S | 33 
 tests/tcg/hexagon/test_vcmpb.S | 32 +++
 tests/tcg/hexagon/test_vcmpw.S | 29 ++
 tests/tcg/hexagon/test_vcmpy.S | 50 
 tests/tcg/hexagon/test_vlsrw.S | 23 +++
 tests/tcg/hexagon/test_vmaxh.S | 37 ++
 tests/tcg/hexagon/test_vminh.S | 37 ++
 tests/tcg/hexagon/test_vpmpyh.S| 30 ++
 tests/tcg/hexagon/test_vspliceb.S  | 33 
 30 files changed, 965 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/hexagon/crt.S
 create mode 100644 tests/tcg/hexagon/test_abs.S
 create mode 100644 tests/tcg/hexagon/test_bitcnt.S
 create mode 100644 tests/tcg/hexagon/test_bitsplit.S
 create mode 100644 tests/tcg/hexagon/test_call.S
 create mode 100644 tests/tcg/hexagon/test_clobber.S
 create mode 100644 tests/tcg/hexagon/test_cmp.S
 create mode 100644 tests/tcg/hexagon/test_cmpy.S
 create mode 100644 tests/tcg/hexagon/test_dotnew.S
 create mode 100644 tests/tcg/hexagon/test_ext.S
 create mode 100644 tests/tcg/hexagon/test_fibonacci.S
 create mode 100644 tests/tcg/hexagon/test_hl.S
 create mode 100644 tests/tcg/hexagon/test_hwloops.S
 create mode 100644 tests/tcg/hexagon/test_jmp.S
 create mode 100644 tests/tcg/hexagon/test_lsr.S
 create mode 100644 tests/tcg/hexagon/test_mpyi.S
 create mode 100644 tests/tcg/hexagon/test_overflow.S
 create mode 100644 tests/tcg/hexagon/test_packet.S
 create mode 100644 tests/tcg/hexagon/test_reorder.S
 create mode 100644 tests/tcg/hexagon/test_round.S
 create mode 100644 tests/tcg/hexagon/test_vavgw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpb.S
 create mode 100644 tests/tcg/hexagon/test_vcmpw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpy.S
 create mode 100644 tests/tcg/hexagon/test_vlsrw.S
 create mode 100644 tests/tcg/hexagon/test_vmaxh.S
 create mode 100644 tests/tcg/hexagon/test_vminh.S
 create mode 100644 tests/tcg/hexagon/test_vpmpyh.S
 create mode 100644 tests/tcg/hexagon/test_vspliceb.S

diff --git a/tests/tcg/hexagon/Makefile.target 
b/tests/tcg/hexagon/Makefile.target
index 050cd61c1a..6709433a52 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -24,7 +24,7 @@ CFLAGS += -fno-unroll-loops
 HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon
 VPATH += $(HEX_SRC)
 
-first: $(HEX_SRC)/first.S
+%: $(HEX_SRC)/%.S $(HEX_SRC)/crt.S
$(CC) -static -mv67 -nostdlib $^ -o $@
 
 HEX_TESTS = first
@@ -40,4 +40,32 @@ HEX_TESTS += load_align
 HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+HEX_TESTS += test_cmpy
+HEX_TESTS += test_dotnew
+HEX_TESTS += test_ext
+HEX_TESTS += test_fibonacci
+HEX_TESTS += test_hl
+HEX_TESTS += test_hwloops
+HEX_TESTS += test_jmp
+HEX_TESTS += test_lsr
+HEX_TESTS += test_mpyi
+HEX_TESTS += test_overflow
+HEX_TESTS += test_packet
+HEX_TESTS += test_reorder
+HEX_TESTS += test_round
+HEX_TESTS += test_vavgw
+HEX_TESTS += test_vcmpb
+HEX_TESTS += test_vcmpw
+HEX_TESTS += test_vcmpy
+HEX_TESTS += test_vlsrw
+HEX_TESTS += test_vmaxh
+HEX_TESTS += test_vminh
+HEX_TESTS += test_vpmpyh
+HEX_TESTS += test_vspliceb
+
 TESTS += $(HEX_TESTS)
diff --git a/tests/tcg/hexagon/crt.S b/tests/tcg/hexagon/crt.S
new file mode 100644
index 00..cb119ae407
--- /dev/null
+++ b/tests/tcg/hexagon/crt.S
@@ -0,0 +1,26 @@
+#define SYS_exit_group   94
+
+.text
+.globl init
+init:
+{
+allocframe(r29,#0):raw
+}
+{
+r0=#256
+}
+{
+dealloc_return
+}
+
+.globl pass
+pass:
+r0 = #0
+r6 = #SYS

[PATCH v6 04/12] target/hexagon: make helper functions non-static

2021-07-20 Thread Alessandro Di Federico via
From: Paolo Montesel 

Make certain helper functions non-static, making them available outside
genptr.c. These functions are required by code generated by the
idef-parser.

This commit also makes some op_helper.c non-static in order to avoid
having them marked as unused when using the idef-parser generated code.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Reviewed-by: Richard Henderson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/genptr.h| 30 +++
 target/hexagon/op_helper.h | 37 
 target/hexagon/genptr.c| 59 +-
 target/hexagon/op_helper.c | 29 +--
 4 files changed, 113 insertions(+), 42 deletions(-)
 create mode 100644 target/hexagon/op_helper.h

diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h
index c158005d2a..d71dd7e1ce 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -19,7 +19,37 @@
 #define HEXAGON_GENPTR_H
 
 #include "insn.h"
+#include "tcg/tcg.h"
+#include "translate.h"
 
 extern const SemanticInsn opcode_genptr[];
 
+void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot);
+void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+uint32_t slot);
+void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+uint32_t slot);
+void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+uint32_t slot);
+void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, DisasContext *ctx,
+uint32_t slot);
+void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
+ uint32_t slot);
+void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
+ uint32_t slot);
+void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
+ uint32_t slot);
+void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, DisasContext *ctx,
+ uint32_t slot);
+TCGv gen_read_preg(TCGv pred, uint8_t num);
+void gen_log_reg_write(int rnum, TCGv val);
+void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val);
+TCGv gen_8bitsof(TCGv result, TCGv value);
+void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src);
+TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign);
+TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign);
+TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign);
+void gen_set_half(int N, TCGv result, TCGv src);
+void gen_set_half_i64(int N, TCGv_i64 result, TCGv src);
+
 #endif
diff --git a/target/hexagon/op_helper.h b/target/hexagon/op_helper.h
new file mode 100644
index 00..2d39637b8f
--- /dev/null
+++ b/target/hexagon/op_helper.h
@@ -0,0 +1,37 @@
+/*
+ *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *
+ *  This program 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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef HEXAGON_OP_HELPER_H
+#define HEXAGON_OP_HELPER_H
+
+/* Misc functions */
+void cancel_slot(CPUHexagonState *env, uint32_t slot);
+void write_new_pc(CPUHexagonState *env, target_ulong addr);
+
+uint8_t mem_load1(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
+uint16_t mem_load2(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
+uint32_t mem_load4(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
+uint64_t mem_load8(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
+
+void log_reg_write(CPUHexagonState *env, int rnum, target_ulong val,
+   uint32_t slot);
+void log_store64(CPUHexagonState *env, target_ulong addr, int64_t val,
+ int width, int slot);
+void log_store32(CPUHexagonState *env, target_ulong addr, target_ulong val,
+ int width, int slot);
+
+#endif
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 2c7f4136b5..5e7f446657 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -26,6 +26,13 @@
 #include "macros.h"
 #undef QEMU_GENERATE
 #include "gen_tcg.h"
+#include "genptr.h"
+
+TCGv gen_read_preg(TCGv pred, uint8_t num)
+{
+tcg_gen_mov_tl(pred, hex_pred[num]);
+return pred;
+}
 
 static inline void gen_log_predicated_reg_write(int rnum, TCGv val,
 uint32_t slot)
@@ -52,7 +59,7 @@ static inline void gen_log_p

[PATCH v6 03/12] target/hexagon: make slot number an unsigned

2021-07-20 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Acked-by: Richard Henderson 
---
 target/hexagon/macros.h |  2 +-
 target/hexagon/genptr.c | 24 +---
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 094b8dabb5..cd4f878fcf 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -185,7 +185,7 @@
 #define LOAD_CANCEL(EA) do { CANCEL; } while (0)
 
 #ifdef QEMU_GENERATE
-static inline void gen_pred_cancel(TCGv pred, int slot_num)
+static inline void gen_pred_cancel(TCGv pred, uint32_t slot_num)
  {
 TCGv slot_mask = tcg_const_tl(1 << slot_num);
 TCGv tmp = tcg_temp_new();
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 7333299615..2c7f4136b5 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -27,7 +27,8 @@
 #undef QEMU_GENERATE
 #include "gen_tcg.h"
 
-static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot)
+static inline void gen_log_predicated_reg_write(int rnum, TCGv val,
+uint32_t slot)
 {
 TCGv zero = tcg_const_tl(0);
 TCGv slot_mask = tcg_temp_new();
@@ -60,7 +61,8 @@ static inline void gen_log_reg_write(int rnum, TCGv val)
 }
 }
 
-static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int slot)
+static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val,
+  uint32_t slot)
 {
 TCGv val32 = tcg_temp_new();
 TCGv zero = tcg_const_tl(0);
@@ -379,7 +381,7 @@ static inline void gen_store_conditional8(DisasContext *ctx,
 tcg_gen_movi_tl(hex_llsc_addr, ~0);
 }
 
-static inline void gen_store32(TCGv vaddr, TCGv src, int width, int slot)
+static inline void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot)
 {
 tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
 tcg_gen_movi_tl(hex_store_width[slot], width);
@@ -387,14 +389,14 @@ static inline void gen_store32(TCGv vaddr, TCGv src, int 
width, int slot)
 }
 
 static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, int slot)
+  DisasContext *ctx, uint32_t slot)
 {
 gen_store32(vaddr, src, 1, slot);
 ctx->store_width[slot] = 1;
 }
 
 static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
-   DisasContext *ctx, int slot)
+   DisasContext *ctx, uint32_t slot)
 {
 TCGv tmp = tcg_const_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
@@ -402,14 +404,14 @@ static inline void gen_store1i(TCGv_env cpu_env, TCGv 
vaddr, int32_t src,
 }
 
 static inline void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, int slot)
+  DisasContext *ctx, uint32_t slot)
 {
 gen_store32(vaddr, src, 2, slot);
 ctx->store_width[slot] = 2;
 }
 
 static inline void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
-   DisasContext *ctx, int slot)
+   DisasContext *ctx, uint32_t slot)
 {
 TCGv tmp = tcg_const_tl(src);
 gen_store2(cpu_env, vaddr, tmp, ctx, slot);
@@ -417,14 +419,14 @@ static inline void gen_store2i(TCGv_env cpu_env, TCGv 
vaddr, int32_t src,
 }
 
 static inline void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, int slot)
+  DisasContext *ctx, uint32_t slot)
 {
 gen_store32(vaddr, src, 4, slot);
 ctx->store_width[slot] = 4;
 }
 
 static inline void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
-   DisasContext *ctx, int slot)
+   DisasContext *ctx, uint32_t slot)
 {
 TCGv tmp = tcg_const_tl(src);
 gen_store4(cpu_env, vaddr, tmp, ctx, slot);
@@ -432,7 +434,7 @@ static inline void gen_store4i(TCGv_env cpu_env, TCGv 
vaddr, int32_t src,
 }
 
 static inline void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src,
-  DisasContext *ctx, int slot)
+  DisasContext *ctx, uint32_t slot)
 {
 tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
 tcg_gen_movi_tl(hex_store_width[slot], 8);
@@ -441,7 +443,7 @@ static inline void gen_store8(TCGv_env cpu_env, TCGv vaddr, 
TCGv_i64 src,
 }
 
 static inline void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src,
-   DisasContext *ctx, int slot)
+   DisasContext *ctx, uint32_t slot)
 {
 TCGv_i64 tmp = tcg_const_i64(src);
 gen_store8(cpu_env, vaddr, tmp, ctx, slot);
-- 
2.32.0




[PATCH v6 06/12] target/hexagon: expose next PC in DisasContext

2021-07-20 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Reviewed-by: Richard Henderson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/translate.h | 1 +
 target/hexagon/translate.c | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 703fd1345f..d5a7fece31 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -37,6 +37,7 @@ typedef struct DisasContext {
 DECLARE_BITMAP(pregs_written, NUM_PREGS);
 uint8_t store_width[STORES_MAX];
 bool s1_store_processed;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index b23d36adf5..63cdf9b90d 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -509,11 +509,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, &pkt, false) > 0) {
 HEX_DEBUG_PRINT_PKT(&pkt);
 gen_start_packet(ctx, &pkt);
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, &pkt.insn[i], &pkt);
 }
 gen_commit_packet(ctx, &pkt);
-ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
+ctx->base.pc_next = ctx->npc;
 } else {
 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET);
 }
-- 
2.32.0




[PATCH v6 05/12] target/hexagon: introduce new helper functions

2021-07-20 Thread Alessandro Di Federico via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 target/hexagon/genptr.h |  15 +-
 target/hexagon/macros.h |   9 
 target/hexagon/genptr.c | 113 +---
 3 files changed, 129 insertions(+), 8 deletions(-)

diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h
index d71dd7e1ce..6bd54cc7f4 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -24,7 +24,8 @@
 
 extern const SemanticInsn opcode_genptr[];
 
-void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot);
+void gen_store32(DisasContext *ctx, TCGv vaddr, TCGv src, tcg_target_long 
width,
+ uint32_t slot);
 void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
 uint32_t slot);
 void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
@@ -44,6 +45,17 @@ void gen_store8i(TCGv_env cpu_env, TCGv vaddr, int64_t src, 
DisasContext *ctx,
 TCGv gen_read_preg(TCGv pred, uint8_t num);
 void gen_log_reg_write(int rnum, TCGv val);
 void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val);
+void gen_write_new_pc(TCGv addr);
+void gen_set_usr_field(int field, TCGv val);
+void gen_set_usr_fieldi(int field, int x);
+void gen_sat_i32(TCGv dest, TCGv source, int width);
+void gen_sat_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width);
+void gen_satu_i32(TCGv dest, TCGv source, int width);
+void gen_satu_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width);
+void gen_sat_i64(TCGv_i64 dest, TCGv_i64 source, int width);
+void gen_sat_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int width);
+void gen_satu_i64(TCGv_i64 dest, TCGv_i64 source, int width);
+void gen_satu_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int width);
 TCGv gen_8bitsof(TCGv result, TCGv value);
 void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src);
 TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign);
@@ -51,5 +63,6 @@ TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool 
sign);
 TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign);
 void gen_set_half(int N, TCGv result, TCGv src);
 void gen_set_half_i64(int N, TCGv_i64 result, TCGv src);
+TCGv gen_read_reg(TCGv result, int num);
 
 #endif
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index cd4f878fcf..2dabdbb49e 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -180,7 +180,16 @@
 #define MEM_STORE8(VA, DATA, SLOT) log_store64(env, VA, DATA, 8, SLOT)
 #endif
 
+#ifdef QEMU_GENERATE
+static inline void gen_cancel(uint32_t slot)
+{
+tcg_gen_ori_tl(hex_slot_cancelled, hex_slot_cancelled, 1 << slot);
+}
+
+#define CANCEL gen_cancel(slot);
+#else
 #define CANCEL cancel_slot(env, slot)
+#endif
 
 #define LOAD_CANCEL(EA) do { CANCEL; } while (0)
 
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 5e7f446657..b7eca94de7 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -28,6 +28,12 @@
 #include "gen_tcg.h"
 #include "genptr.h"
 
+TCGv gen_read_reg(TCGv result, int num)
+{
+tcg_gen_mov_tl(result, hex_gpr[num]);
+return result;
+}
+
 TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
@@ -388,18 +394,19 @@ static inline void gen_store_conditional8(DisasContext 
*ctx,
 tcg_gen_movi_tl(hex_llsc_addr, ~0);
 }
 
-void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot)
+void gen_store32(DisasContext *ctx, TCGv vaddr, TCGv src, tcg_target_long 
width,
+ uint32_t slot)
 {
 tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
 tcg_gen_movi_tl(hex_store_width[slot], width);
 tcg_gen_mov_tl(hex_store_val32[slot], src);
+ctx->store_width[slot] = width;
 }
 
 void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
 uint32_t slot)
 {
-gen_store32(vaddr, src, 1, slot);
-ctx->store_width[slot] = 1;
+gen_store32(ctx, vaddr, src, 1, slot);
 }
 
 void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
@@ -413,8 +420,7 @@ void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, 
DisasContext *ctx,
 void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
 uint32_t slot)
 {
-gen_store32(vaddr, src, 2, slot);
-ctx->store_width[slot] = 2;
+gen_store32(ctx, vaddr, src, 2, slot);
 }
 
 void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
@@ -428,8 +434,7 @@ void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src, 
DisasContext *ctx,
 void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
 uint32_t slot)
 {
-gen_store32(vaddr, src, 4, slot);
-ctx->store_width[slot] = 4;
+gen_store32(ctx, vaddr, src, 4, slot);
 }
 
 void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
@@ -468,5 +473,99 @@ TCGv gen_8bitsof(TCGv r

[PATCH v6 01/12] target/hexagon: update MAINTAINERS for idef-parser

2021-07-20 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4256ad1adb..6c825a9eb4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -194,6 +194,8 @@ Hexagon TCG CPUs
 M: Taylor Simpson 
 S: Supported
 F: target/hexagon/
+X: target/hexagon/idef-parser/
+X: target/hexagon/gen_idef_parser_funcs.py
 F: linux-user/hexagon/
 F: tests/tcg/hexagon/
 F: disas/hexagon.c
@@ -201,6 +203,12 @@ F: configs/targets/hexagon-linux-user/default.mak
 F: docker/dockerfiles/debian-hexagon-cross.docker
 F: docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh
 
+Hexagon idef-parser
+M: Alessandro Di Federico 
+S: Supported
+F: target/hexagon/idef-parser/
+F: target/hexagon/gen_idef_parser_funcs.py
+
 HPPA (PA-RISC) TCG CPUs
 M: Richard Henderson 
 S: Maintained
-- 
2.32.0




Re: [PATCH v5 14/14] gitlab-ci: do not use qemu-project Docker registry

2021-07-08 Thread Alessandro Di Federico via
On Tue, 29 Jun 2021 15:37:21 +0100
Daniel P. Berrangé  wrote:

> We have either one or two images.  If this is a new user fork,
> we only have the $COMMON_TAG image in the main QEMU registry.
> If this is a existing fork, we might have two images, one in
> the main QEMU registry and one in the user's fork registry.
> Both of the images are to be used as a cache source, with
> the container tools figuring out which has matching image
> layers, if any.
>
> This proposed change makes TAG and COMMON_TAG identical
> which means we loose inheritance from the main QEMU
> registry, which almost always has suitable cached content.

I understand. This patch was aimed at pointing out a problem more than
offering a proper solution.

I'll try and take a look at how to do this right, but I think this
outside the scope of this patchset (and my area of expertise).

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v5 10/14] target/hexagon: import parser for idef-parser

2021-07-05 Thread Alessandro Di Federico via
On Thu, 24 Jun 2021 03:55:35 +
Taylor Simpson  wrote:

> > +void gen_deposit_op(Context *c,
> > +YYLTYPE *locp,
> > +HexValue *dest,
> > +HexValue *value,
> > +HexValue *index,
> > +HexCast *cast)  
> 
> What's the difference between this and the gen_rdeposit_op above?

`gen_deposit_op` expects index and width (cast) to be immediates, while
`gen_rdeposit_op` does not.
We could merge them together, but it would just be a big "if" over the
whole function.

> > +HexValue gen_rextract_op(Context *c,
> > + YYLTYPE *locp,
> > + HexValue *source,
> > + int begin,
> > + int width) {
> > +
> > +HexValue gen_extract_op(Context *c,
> > +YYLTYPE *locp,
> > +HexValue *source,
> > +HexValue *index,
> > +HexExtract *extract) {  
> 
> What's the difference between this ant the gen_rextract_op above?

As before.

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v5 13/14] target/hexagon: import additional tests

2021-07-05 Thread Alessandro Di Federico via
On Fri, 25 Jun 2021 18:56:57 -0500
Taylor Simpson  wrote:

> Each of these are very small, so I recommend putting them into misc.c
> or combine all the assembly into a small number of executables.

These tests are designed to run without libc and test in isolation very
specific functionality making as little assumptions as possible about
what instructions are working correctly.

Now that we are mature enough it might not make much sense this
approach, but starting from scratch (and also considering phase 2) they
might be helpful.

With some refactoring and ".include" directives I can probably make a
single executable out of them, but it's not superelegant.

For the rest, I've dropped several outdated comments and superflous
tests.

Thanks for looking into this.

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v5 14/14] gitlab-ci: do not use qemu-project Docker registry

2021-06-29 Thread Alessandro Di Federico via
On Sat, 19 Jun 2021 11:37:13 +0200
Alessandro Di Federico  wrote:

> From: Alessandro Di Federico 
> 
> This commit is necessary in order to use container built by the
> current run of the CI. If we don't do this, we use official
> containers which are not affected by the additional dependencies
> we're introducing.
> 
> Signed-off-by: Alessandro Di Federico 

Alex, what do you think about this?

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v5 10/14] target/hexagon: import parser for idef-parser

2021-06-29 Thread Alessandro Di Federico via
On Thu, 24 Jun 2021 03:55:35 +
Taylor Simpson  wrote:

> > +   | rvalue '[' rvalue ']'
> > + {
> > + @1.last_column = @4.last_column;
> > + if ($3.type == IMMEDIATE) {
> > + $$ = gen_tmp(c, &@1, $1.bit_width);
> > + OUT(c, &@1, "tcg_gen_extract_i", &$$.bit_width,
> > "(");
> > + OUT(c, &@1, &$$, ", ", &$1, ", ", &$3, ", 1);\n");
> > + } else {
> > + HexValue one = gen_imm_value(c, &@1, 1,
> > $3.bit_width);
> > + HexValue tmp = gen_bin_op(c, &@1, ASR_OP, &$1,
> > &$3);
> > + $$ = gen_bin_op(c, &@1, ANDB_OP, &tmp, &one);  
> 
> Can this be done with a tcg_gen_extract_tl or tcg_gen_sextract_tl?

Those require translation-time constants as offsets while we need TCGv:

tcg_gen_extract_i32(TCGv_i32 ret,
TCGv_i32 arg,
unsigned int ofs,
unsigned int len);

> Do you need to worry about signed-ness?

`gen_bin_op` should take care of that.

On Thu, 24 Jun 2021 03:55:35 +
Taylor Simpson  wrote:

> > +void imm_print(Context *c, YYLTYPE *locp, HexImm *imm)
> > +{
> > +switch (imm->type) {
> > +case I:
> > +EMIT(c, "i");
> > +break;
> > +case VARIABLE:
> > +EMIT(c, "%ciV", imm->id);
> > +break;
> > +case VALUE:
> > +EMIT(c, "((int64_t)%" PRIu64 "ULL)", (int64_t)imm->value);
> > +break;
> > +case QEMU_TMP:
> > +EMIT(c, "qemu_tmp_%" PRIu64, imm->index);
> > +break;
> > +case IMM_PC:
> > +EMIT(c, "ctx->base.pc_next");
> > +break;
> > +case IMM_NPC:
> > +EMIT(c, "ctx->npc");
> > +break;
> > +case IMM_CONSTEXT:
> > +EMIT(c, "insn->extension_valid");  
> 
> The extension_valid field is a bool indicating if the instruction has
> a constant extender.  Don't you want the actual value here?

No, this maps to Constant_extended:

#define fREAD_GP() (Constant_extended ? (0) : GP)

Constant extensions is handle for us externally.

On Thu, 24 Jun 2021 03:55:35 +
Taylor Simpson  wrote:

> > +if (dest->bit_width != res.bit_width) {
> > +res = rvalue_truncate(c, locp, &res);
> > +}
> > +
> > +HexValue zero = gen_tmp_value(c, locp, "0", res.bit_width);
> > +OUT(c, locp, "tcg_gen_movcond_i", &res.bit_width,
> > "(TCG_COND_NE, ", dest);
> > +OUT(c, locp, ", ", &width_orig, ", ", &zero, ", ", &res, ", ",
> > dest,
> > +");\n");
> > +
> > +rvalue_free(c, locp, &zero);
> > +rvalue_free(c, locp, width);
> > +rvalue_free(c, locp, &res);
> > +}
> > +
> > +void gen_deposit_op(Context *c,
> > +YYLTYPE *locp,
> > +HexValue *dest,
> > +HexValue *value,
> > +HexValue *index,
> > +HexCast *cast)  
> 
> What's the difference between this and the gen_rdeposit_op above?

`gen_rdeposit_op` is general purpose, it takes start and width of the
deposit.
`gen_deposit_op` is more tailored to handle `fINSERT_BITS`.

We will improve `gen_rdeposit_op` in order to handle the immediate
case efficiently and then implement `gen_deposit_op` with
`gen_rdeposit_op`.

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v5 03/14] target/hexagon: import README for idef-parser

2021-06-24 Thread Alessandro Di Federico via
On Wed, 23 Jun 2021 15:46:22 +
Taylor Simpson  wrote:

> The output isn't actually indented, but it would be great if it were.
>  This is especially true for instructions where an "if" or "for" show
> up in the emitted code.

Emitting whitespaces in the parser is a bit annoying and fragile, but
it can be done.

We post-process the parser output with `indent` internally. We could
run it after the output is produced, but that would mean a new
dependency.

I'd go for opportunistic indentation through `indent` if installed.

> Is there a way to force the parser not to emit a particular
> instruction (i.e., fall back on the reference implementation)?

Yes, see `gen_idef_parser_funcs.py`.

-- 
Alessandro Di Federico
rev.ng



[PATCH v5 13/14] target/hexagon: import additional tests

2021-06-19 Thread Alessandro Di Federico via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 tests/tcg/hexagon/Makefile.target  | 36 -
 tests/tcg/hexagon/crt.S| 28 +
 tests/tcg/hexagon/test_abs.S   | 20 ++
 tests/tcg/hexagon/test_add.S   | 20 ++
 tests/tcg/hexagon/test_andp.S  | 23 +++
 tests/tcg/hexagon/test_bitcnt.S| 42 
 tests/tcg/hexagon/test_bitsplit.S  | 25 
 tests/tcg/hexagon/test_call.S  | 63 ++
 tests/tcg/hexagon/test_clobber.S   | 35 +
 tests/tcg/hexagon/test_cmp.S   | 34 
 tests/tcg/hexagon/test_cmpy.S  | 31 +++
 tests/tcg/hexagon/test_djump.S | 24 
 tests/tcg/hexagon/test_dotnew.S| 39 ++
 tests/tcg/hexagon/test_dstore.S| 29 ++
 tests/tcg/hexagon/test_ext.S   | 18 +
 tests/tcg/hexagon/test_fibonacci.S | 33 
 tests/tcg/hexagon/test_hello.S | 21 ++
 tests/tcg/hexagon/test_hl.S| 19 +
 tests/tcg/hexagon/test_hwloops.S   | 25 
 tests/tcg/hexagon/test_jmp.S   | 25 
 tests/tcg/hexagon/test_lsr.S   | 39 ++
 tests/tcg/hexagon/test_mpyi.S  | 20 ++
 tests/tcg/hexagon/test_overflow.S  | 63 ++
 tests/tcg/hexagon/test_packet.S| 26 
 tests/tcg/hexagon/test_reorder.S   | 31 +++
 tests/tcg/hexagon/test_round.S | 31 +++
 tests/tcg/hexagon/test_vavgw.S | 33 
 tests/tcg/hexagon/test_vcmpb.S | 32 +++
 tests/tcg/hexagon/test_vcmpw.S | 29 ++
 tests/tcg/hexagon/test_vcmpy.S | 50 
 tests/tcg/hexagon/test_vlsrw.S | 23 +++
 tests/tcg/hexagon/test_vmaxh.S | 37 ++
 tests/tcg/hexagon/test_vminh.S | 37 ++
 tests/tcg/hexagon/test_vpmpyh.S| 30 ++
 tests/tcg/hexagon/test_vspliceb.S  | 33 
 35 files changed, 1103 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/hexagon/crt.S
 create mode 100644 tests/tcg/hexagon/test_abs.S
 create mode 100644 tests/tcg/hexagon/test_add.S
 create mode 100644 tests/tcg/hexagon/test_andp.S
 create mode 100644 tests/tcg/hexagon/test_bitcnt.S
 create mode 100644 tests/tcg/hexagon/test_bitsplit.S
 create mode 100644 tests/tcg/hexagon/test_call.S
 create mode 100644 tests/tcg/hexagon/test_clobber.S
 create mode 100644 tests/tcg/hexagon/test_cmp.S
 create mode 100644 tests/tcg/hexagon/test_cmpy.S
 create mode 100644 tests/tcg/hexagon/test_djump.S
 create mode 100644 tests/tcg/hexagon/test_dotnew.S
 create mode 100644 tests/tcg/hexagon/test_dstore.S
 create mode 100644 tests/tcg/hexagon/test_ext.S
 create mode 100644 tests/tcg/hexagon/test_fibonacci.S
 create mode 100644 tests/tcg/hexagon/test_hello.S
 create mode 100644 tests/tcg/hexagon/test_hl.S
 create mode 100644 tests/tcg/hexagon/test_hwloops.S
 create mode 100644 tests/tcg/hexagon/test_jmp.S
 create mode 100644 tests/tcg/hexagon/test_lsr.S
 create mode 100644 tests/tcg/hexagon/test_mpyi.S
 create mode 100644 tests/tcg/hexagon/test_overflow.S
 create mode 100644 tests/tcg/hexagon/test_packet.S
 create mode 100644 tests/tcg/hexagon/test_reorder.S
 create mode 100644 tests/tcg/hexagon/test_round.S
 create mode 100644 tests/tcg/hexagon/test_vavgw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpb.S
 create mode 100644 tests/tcg/hexagon/test_vcmpw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpy.S
 create mode 100644 tests/tcg/hexagon/test_vlsrw.S
 create mode 100644 tests/tcg/hexagon/test_vmaxh.S
 create mode 100644 tests/tcg/hexagon/test_vminh.S
 create mode 100644 tests/tcg/hexagon/test_vpmpyh.S
 create mode 100644 tests/tcg/hexagon/test_vspliceb.S

diff --git a/tests/tcg/hexagon/Makefile.target 
b/tests/tcg/hexagon/Makefile.target
index 0992787d50..8f3827016c 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -33,7 +33,7 @@ CFLAGS += -fno-unroll-loops
 HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon
 VPATH += $(HEX_SRC)
 
-first: $(HEX_SRC)/first.S
+%: $(HEX_SRC)/%.S $(HEX_SRC)/crt.S
$(CC) -static -mv67 -nostdlib $^ -o $@
 
 HEX_TESTS = first
@@ -49,4 +49,38 @@ HEX_TESTS += load_align
 HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_add
+HEX_TESTS += test_andp
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_call
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+HEX_TESTS += test_cmpy
+HEX_TESTS += test_djump
+HEX_TESTS += test_dotnew
+HEX_TESTS += test_dstore
+HEX_TESTS += test_ext
+HEX_TESTS += test_fibonacci
+HEX_TESTS += test_hello
+HEX_TESTS += test_hl
+HEX_TESTS += test_hwloops
+HEX_TESTS += test_jmp
+HEX_TESTS += test_lsr
+HEX_TESTS += test_mpyi
+HEX_TESTS += test_overflow
+HEX_TESTS += test_packet
+HEX_TESTS += test_reorder
+HEX_TESTS += tes

[PATCH v5 03/14] target/hexagon: import README for idef-parser

2021-06-19 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/README |   5 +
 target/hexagon/idef-parser/README.rst | 447 ++
 2 files changed, 452 insertions(+)
 create mode 100644 target/hexagon/idef-parser/README.rst

diff --git a/target/hexagon/README b/target/hexagon/README
index b0b2435070..2f2814380c 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -23,6 +23,10 @@ Hexagon-specific code are
 encode*.def Encoding patterns for each instruction
 iclass.def  Instruction class definitions used to determine
 legal VLIW slots for each instruction
+qemu/target/hexagon/idef-parser
+Parser that, given the high-level definitions of an instruction,
+produces a C function generating equivalent tiny code instructions.
+See README.rst.
 qemu/linux-user/hexagon
 Helpers for loading the ELF file and making Linux system calls,
 signals, etc
@@ -43,6 +47,7 @@ header files in /target/hexagon
 gen_tcg_funcs.py-> tcg_funcs_generated.c.inc
 gen_tcg_func_table.py   -> tcg_func_table_generated.c.inc
 gen_helper_funcs.py -> helper_funcs_generated.c.inc
+gen_idef_parser_funcs.py-> idef_parser_input.h
 
 Qemu helper functions have 3 parts
 DEF_HELPER declaration indicates the signature of the helper
diff --git a/target/hexagon/idef-parser/README.rst 
b/target/hexagon/idef-parser/README.rst
new file mode 100644
index 00..f4cb416e8b
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,447 @@
+Hexagon ISA instruction definitions to tinycode generator compiler
+--
+
+idef-parser is a small compiler able to translate the Hexagon ISA description
+language into tinycode generator code, that can be easily integrated into QEMU.
+
+Compilation Example
+---
+
+To better understand the scope of the idef-parser, we'll explore an applicative
+example. Let's start by one of the simplest Hexagon instruction: the ``add``.
+
+The ISA description language represents the ``add`` instruction as
+follows:
+
+.. code:: c
+
+   A2_add(RdV, in RsV, in RtV) {
+   { RdV=RsV+RtV;}
+   }
+
+idef-parser will compile the above code into the following code:
+
+.. code:: c
+
+   /* A2_add */
+   void emit_A2_add(DisasContext *ctx, Insn *insn, Packet *pkt, TCGv_i32 RdV,
+TCGv_i32 RsV, TCGv_i32 RtV)
+   /*  { RdV=RsV+RtV;} */
+   {
+   tcg_gen_movi_i32(RdV, 0);
+   TCGv_i32 tmp_0 = tcg_temp_new_i32();
+   tcg_gen_add_i32(tmp_0, RsV, RtV);
+   tcg_gen_mov_i32(RdV, tmp_0);
+   tcg_temp_free_i32(tmp_0);
+   }
+
+The output of the compilation process will be a function, containing the
+tinycode generator code, implementing the correct semantics. That function will
+not access any global variable, because all the accessed data structures will 
be
+passed explicitly as function parameters. Among the passed parameters we will
+have TCGv (tinycode variables) representing the input and output registers of
+the architecture, integers representing the immediates that come from the code,
+and other data structures which hold information about the disassemblation
+context (``DisasContext`` struct).
+
+Let's begin by describing the input code. The ``add`` instruction is associated
+with a unique identifier, in this case ``A2_add``, which allows to distinguish
+variants of the same instruction, and expresses the class to which the
+instruction belongs, in this case ``A2`` corresponds to the Hexagon
+``ALU32/ALU`` instruction subclass.
+
+After the instruction identifier, we have a series of parameters that 
represents
+TCG variables that will be passed to the generated function. Parameters marked
+with ``in`` are already initialized, while the others are output parameters.
+
+We will leverage this information to infer several information:
+
+-  Fill in the output function signature with the correct TCGv registers
+-  Fill in the output function signature with the immediate integers
+-  Keep track of which registers, among the declared one, have been
+   initialized
+
+Let's now observe the actual instruction description code, in this case:
+
+.. code:: c
+
+   { RdV=RsV+RtV;}
+
+This code is composed by a subset of the C syntax, and is the result of the
+application of some macro definitions contained in the ``macros.h`` file.
+
+This file is used to reduce the complexity of the input language where complex
+variants of similar constructs can be mapped to a unique primitive, so that the
+idef-parser has to handle a lower number of computation primitives.
+
+As you may notice, the description code modifies the registers which have been
+declared by the declaration statements. In this case all the three registers
+will be declared, ``RsV`` and ``RtV`` wil

[PATCH v5 12/14] target/hexagon: remove unused macros and functions

2021-06-19 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/gen_tcg.h   | 528 -
 target/hexagon/genptr.c|  98 ---
 target/hexagon/macros.h| 200 +-
 target/hexagon/op_helper.c | 119 -
 4 files changed, 9 insertions(+), 936 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 18fcdbc7e4..f1dd1b64c1 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -43,381 +43,6 @@
  * _pcr  post increment circular register  r0 = memw(r1++I:circ(m0))
  */
 
-/* Macros for complex addressing modes */
-#define GET_EA_ap \
-do { \
-fEA_IMM(UiV); \
-tcg_gen_movi_tl(ReV, UiV); \
-} while (0)
-#define GET_EA_pr \
-do { \
-fEA_REG(RxV); \
-fPM_M(RxV, MuV); \
-} while (0)
-#define GET_EA_pbr \
-do { \
-gen_helper_fbrev(EA, RxV); \
-tcg_gen_add_tl(RxV, RxV, MuV); \
-} while (0)
-#define GET_EA_pi \
-do { \
-fEA_REG(RxV); \
-fPM_I(RxV, siV); \
-} while (0)
-#define GET_EA_pci \
-do { \
-TCGv tcgv_siV = tcg_const_tl(siV); \
-tcg_gen_mov_tl(EA, RxV); \
-gen_helper_fcircadd(RxV, RxV, tcgv_siV, MuV, \
-hex_gpr[HEX_REG_CS0 + MuN]); \
-tcg_temp_free(tcgv_siV); \
-} while (0)
-#define GET_EA_pcr(SHIFT) \
-do { \
-TCGv ireg = tcg_temp_new(); \
-tcg_gen_mov_tl(EA, RxV); \
-gen_read_ireg(ireg, MuV, (SHIFT)); \
-gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
-tcg_temp_free(ireg); \
-} while (0)
-
-/* Instructions with multiple definitions */
-#define fGEN_TCG_LOAD_AP(RES, SIZE, SIGN) \
-do { \
-fMUST_IMMEXT(UiV); \
-fEA_IMM(UiV); \
-fLOAD(1, SIZE, SIGN, EA, RES); \
-tcg_gen_movi_tl(ReV, UiV); \
-} while (0)
-
-#define fGEN_TCG_L4_loadrub_ap(SHORTCODE) \
-fGEN_TCG_LOAD_AP(RdV, 1, u)
-#define fGEN_TCG_L4_loadrb_ap(SHORTCODE) \
-fGEN_TCG_LOAD_AP(RdV, 1, s)
-#define fGEN_TCG_L4_loadruh_ap(SHORTCODE) \
-fGEN_TCG_LOAD_AP(RdV, 2, u)
-#define fGEN_TCG_L4_loadrh_ap(SHORTCODE) \
-fGEN_TCG_LOAD_AP(RdV, 2, s)
-#define fGEN_TCG_L4_loadri_ap(SHORTCODE) \
-fGEN_TCG_LOAD_AP(RdV, 4, u)
-#define fGEN_TCG_L4_loadrd_ap(SHORTCODE) \
-fGEN_TCG_LOAD_AP(RddV, 8, u)
-
-#define fGEN_TCG_L2_loadrub_pci(SHORTCODE)SHORTCODE
-#define fGEN_TCG_L2_loadrb_pci(SHORTCODE) SHORTCODE
-#define fGEN_TCG_L2_loadruh_pci(SHORTCODE)SHORTCODE
-#define fGEN_TCG_L2_loadrh_pci(SHORTCODE) SHORTCODE
-#define fGEN_TCG_L2_loadri_pci(SHORTCODE) SHORTCODE
-#define fGEN_TCG_L2_loadrd_pci(SHORTCODE) SHORTCODE
-
-#define fGEN_TCG_LOAD_pcr(SHIFT, LOAD) \
-do { \
-TCGv ireg = tcg_temp_new(); \
-tcg_gen_mov_tl(EA, RxV); \
-gen_read_ireg(ireg, MuV, SHIFT); \
-gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
-LOAD; \
-tcg_temp_free(ireg); \
-} while (0)
-
-#define fGEN_TCG_L2_loadrub_pcr(SHORTCODE) \
-  fGEN_TCG_LOAD_pcr(0, fLOAD(1, 1, u, EA, RdV))
-#define fGEN_TCG_L2_loadrb_pcr(SHORTCODE) \
-  fGEN_TCG_LOAD_pcr(0, fLOAD(1, 1, s, EA, RdV))
-#define fGEN_TCG_L2_loadruh_pcr(SHORTCODE) \
-  fGEN_TCG_LOAD_pcr(1, fLOAD(1, 2, u, EA, RdV))
-#define fGEN_TCG_L2_loadrh_pcr(SHORTCODE) \
-  fGEN_TCG_LOAD_pcr(1, fLOAD(1, 2, s, EA, RdV))
-#define fGEN_TCG_L2_loadri_pcr(SHORTCODE) \
-  fGEN_TCG_LOAD_pcr(2, fLOAD(1, 4, u, EA, RdV))
-#define fGEN_TCG_L2_loadrd_pcr(SHORTCODE) \
-  fGEN_TCG_LOAD_pcr(3, fLOAD(1, 8, u, EA, RddV))
-
-#define fGEN_TCG_L2_loadrub_pr(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadrub_pbr(SHORTCODE) SHORTCODE
-#define fGEN_TCG_L2_loadrub_pi(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadrb_pr(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadrb_pbr(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadrb_pi(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadruh_pr(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadruh_pbr(SHORTCODE) SHORTCODE
-#define fGEN_TCG_L2_loadruh_pi(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadrh_pr(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadrh_pbr(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadrh_pi(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadri_pr(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadri_pbr(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadri_pi(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadrd_pr(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadrd_pbr(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadrd_pi(SHORTCODE)   SHORTCODE
-
-/*
- * These instructions load 2 bytes and places them in
- * two halves of the destination register.
- * The GET_EA macro determines the addressing mode.
- * The SIGN argument determines whether to zero-extend or
- * sign-extend.
- */
-#define fGEN_TCG_loadbXw2(GET_EA, S

[PATCH v5 14/14] gitlab-ci: do not use qemu-project Docker registry

2021-06-19 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This commit is necessary in order to use container built by the current
run of the CI. If we don't do this, we use official containers which are
not affected by the additional dependencies we're introducing.

Signed-off-by: Alessandro Di Federico 
---
 .gitlab-ci.d/container-cross.yml| 2 +-
 .gitlab-ci.d/container-template.yml | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.gitlab-ci.d/container-cross.yml b/.gitlab-ci.d/container-cross.yml
index 0fcebe363a..eb134e927d 100644
--- a/.gitlab-ci.d/container-cross.yml
+++ b/.gitlab-ci.d/container-cross.yml
@@ -63,7 +63,7 @@ hexagon-cross-container:
 - docker:dind
   before_script:
 - export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
-- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest"
+- export COMMON_TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
 - docker info
 - docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p 
"$CI_REGISTRY_PASSWORD"
   script:
diff --git a/.gitlab-ci.d/container-template.yml 
b/.gitlab-ci.d/container-template.yml
index 1baecd9460..c85ae377b8 100644
--- a/.gitlab-ci.d/container-template.yml
+++ b/.gitlab-ci.d/container-template.yml
@@ -5,7 +5,7 @@
 - docker:dind
   before_script:
 - export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
-- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/$NAME:latest"
+- export COMMON_TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
 - apk add python3
 - docker info
 - docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p 
"$CI_REGISTRY_PASSWORD"
@@ -14,7 +14,7 @@
 - echo "COMMON_TAG:$COMMON_TAG"
 - ./tests/docker/docker.py --engine docker build
   -t "qemu/$NAME" -f "tests/docker/dockerfiles/$NAME.docker"
-  -r $CI_REGISTRY/qemu-project/qemu
+  -r $CI_REGISTRY_IMAGE
 - docker tag "qemu/$NAME" "$TAG"
 - docker push "$TAG"
   after_script:
-- 
2.31.1




[PATCH v5 02/14] target/hexagon: update MAINTAINERS for idef-parser

2021-06-19 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7d9cd29042..7fd32062be 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -192,6 +192,8 @@ Hexagon TCG CPUs
 M: Taylor Simpson 
 S: Supported
 F: target/hexagon/
+X: target/hexagon/idef-parser/
+X: target/hexagon/gen_idef_parser_funcs.py
 F: linux-user/hexagon/
 F: tests/tcg/hexagon/
 F: disas/hexagon.c
@@ -199,6 +201,12 @@ F: default-configs/targets/hexagon-linux-user.mak
 F: docker/dockerfiles/debian-hexagon-cross.docker
 F: docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh
 
+Hexagon idef-parser
+M: Alessandro Di Federico 
+S: Supported
+F: target/hexagon/idef-parser/
+F: target/hexagon/gen_idef_parser_funcs.py
+
 HPPA (PA-RISC) TCG CPUs
 M: Richard Henderson 
 S: Maintained
-- 
2.31.1




[PATCH v5 11/14] target/hexagon: call idef-parser functions

2021-06-19 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Extend gen_tcg_funcs.py in order to emit calls to the functions emitted
by the idef-parser, if available.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_helper_funcs.py  |  5 ++-
 target/hexagon/gen_helper_protos.py |  5 ++-
 target/hexagon/gen_tcg_funcs.py | 28 +++-
 target/hexagon/hex_common.py| 10 +
 target/hexagon/meson.build  | 68 -
 5 files changed, 82 insertions(+), 34 deletions(-)

diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index 2b1c5d8e3e..40fcc0269a 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -192,11 +192,12 @@ def main():
 hex_common.read_semantics_file(sys.argv[1])
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -213,6 +214,8 @@ def main():
 continue
 if ( hex_common.skip_qemu_helper(tag) ):
 continue
+if ( hex_common.is_idef_parser_enabled(tag) ):
+continue
 
 gen_helper_function(f, tag, tagregs, tagimms)
 
diff --git a/target/hexagon/gen_helper_protos.py 
b/target/hexagon/gen_helper_protos.py
index ea41007ec9..6aee7229cb 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -121,11 +121,12 @@ def main():
 hex_common.read_semantics_file(sys.argv[1])
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -143,6 +144,8 @@ def main():
 
 if ( hex_common.skip_qemu_helper(tag) ):
 continue
+if ( hex_common.is_idef_parser_enabled(tag) ):
+continue
 
 gen_helper_prototype(f, tag, tagregs, tagimms)
 
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 7ceb25b5f6..e12f6b7cfc 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -394,7 +394,29 @@ def gen_tcg_func(f, tag, regs, imms):
 if (hex_common.is_read(regid)):
 genptr_src_read_opn(f,regtype,regid,tag)
 
-if ( hex_common.skip_qemu_helper(tag) ):
+if hex_common.is_idef_parser_enabled(tag):
+declared = []
+## Handle registers
+for regtype,regid,toss,numregs in regs:
+if (hex_common.is_pair(regid)
+or (hex_common.is_single(regid)
+and hex_common.is_old_val(regtype, regid, tag))):
+declared.append("%s%sV" % (regtype, regid))
+if regtype == "M":
+declared.append("%s%sN" % (regtype, regid))
+elif hex_common.is_new_val(regtype, regid, tag):
+declared.append("%s%sN" % (regtype,regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+## Handle immediates
+for immlett,bits,immshift in imms:
+declared.append(hex_common.imm_name(immlett))
+
+arguments = ", ".join(["ctx", "insn", "pkt"] + declared)
+f.write("emit_%s(%s);\n" % (tag, arguments))
+
+elif ( hex_common.skip_qemu_helper(tag) ):
 f.write("fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
 else:
 ## Generate the call to the helper
@@ -455,12 +477,14 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.calculate_attribs()
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
 f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
+f.write("#include \"idef-generated-emitter.h.inc\"\n\n")
 
 for tag in hex_common.tags:
 ## Skip the priv instructions
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index b3b534057d..648ad29e94 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -28,6 +28,7 @@
 attribinfo = {}   # Regi

[PATCH v5 05/14] target/hexagon: make helper functions non-static

2021-06-19 Thread Alessandro Di Federico via
From: Paolo Montesel 

Make certain helper functions non-static, making them available outside
genptr.c. These functions are required by code generated by the
idef-parser.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Reviewed-by: Richard Henderson 
---
 target/hexagon/genptr.c | 7 ---
 target/hexagon/genptr.h | 6 ++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 3b8013d4e2..6f2816f6e2 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -26,8 +26,9 @@
 #include "macros.h"
 #undef QEMU_GENERATE
 #include "gen_tcg.h"
+#include "genptr.h"
 
-static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
+TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
 return pred;
@@ -58,7 +59,7 @@ static inline void gen_log_predicated_reg_write(int rnum, 
TCGv val,
 tcg_temp_free(slot_mask);
 }
 
-static inline void gen_log_reg_write(int rnum, TCGv val)
+void gen_log_reg_write(int rnum, TCGv val)
 {
 tcg_gen_mov_tl(hex_new_value[rnum], val);
 if (HEX_DEBUG) {
@@ -121,7 +122,7 @@ static void gen_log_reg_write_pair(int rnum, TCGv_i64 val)
 }
 }
 
-static inline void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val)
+void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val)
 {
 TCGv zero = tcg_const_tl(0);
 TCGv base_val = tcg_temp_new();
diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h
index c158005d2a..709b8eb099 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -19,7 +19,13 @@
 #define HEXAGON_GENPTR_H
 
 #include "insn.h"
+#include "tcg/tcg.h"
+#include "translate.h"
 
 extern const SemanticInsn opcode_genptr[];
 
+TCGv gen_read_preg(TCGv pred, uint8_t num);
+void gen_log_reg_write(int rnum, TCGv val);
+void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val);
+
 #endif
-- 
2.31.1




[PATCH v5 10/14] target/hexagon: import parser for idef-parser

2021-06-19 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.y  |  961 +++
 target/hexagon/idef-parser/parser-helpers.c   | 2396 +
 target/hexagon/idef-parser/parser-helpers.h   |  347 +++
 target/hexagon/meson.build|   26 +-
 tests/docker/dockerfiles/alpine.docker|1 +
 tests/docker/dockerfiles/centos8.docker   |1 +
 tests/docker/dockerfiles/debian-amd64.docker  |1 +
 tests/docker/dockerfiles/debian10.docker  |2 +
 .../dockerfiles/fedora-i386-cross.docker  |2 +
 .../dockerfiles/fedora-win32-cross.docker |2 +
 .../dockerfiles/fedora-win64-cross.docker |2 +
 tests/docker/dockerfiles/fedora.docker|1 +
 tests/docker/dockerfiles/opensuse-leap.docker |1 +
 tests/docker/dockerfiles/ubuntu.docker|2 +
 tests/docker/dockerfiles/ubuntu1804.docker|2 +
 tests/docker/dockerfiles/ubuntu2004.docker|4 +-
 16 files changed, 3749 insertions(+), 2 deletions(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.y
 create mode 100644 target/hexagon/idef-parser/parser-helpers.c
 create mode 100644 target/hexagon/idef-parser/parser-helpers.h

diff --git a/target/hexagon/idef-parser/idef-parser.y 
b/target/hexagon/idef-parser/idef-parser.y
new file mode 100644
index 00..5e4fbb6e75
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,961 @@
+%{
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "idef-parser.h"
+#include "parser-helpers.h"
+#include "idef-parser.tab.h"
+#include "idef-parser.yy.h"
+
+/* Uncomment this to disable yyasserts */
+/* #define NDEBUG */
+
+#define ERR_LINE_CONTEXT 40
+
+%}
+
+%lex-param {void *scanner}
+%parse-param {void *scanner}
+%parse-param {Context *c}
+
+%define parse.error verbose
+%define parse.lac full
+%define api.pure full
+
+%locations
+
+%union {
+GString *string;
+HexValue rvalue;
+HexSat sat;
+HexCast cast;
+HexExtract extract;
+HexMpy mpy;
+bool is_unsigned;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token INAME DREG DIMM DPRE DEA RREG WREG FREG FIMM RPRE WPRE FPRE FWRAP FEA 
VAR
+%token POW ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS 
ASL
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL ORL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE CONSTLL CONSTULL PC NPC LPCFG
+%token CANCEL IDENTITY PART1 BREV_4 BREV_8 ROTL INSBITS SETBITS EXTBITS 
EXTRANGE
+%token CAST4_8U SETOVF FAIL DEINTERLEAVE INTERLEAVE CARRY_FROM_ADD LSBNEW
+
+%token  REG IMM PRE
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement var
+%type  DREG DIMM DPRE RREG RPRE FAIL
+%type  if_stmt IF
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left '('
+%left ','
+%left '='
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left '?' ':'
+%left ORL
+%left ANDL
+%left '|'
+%left '^' ANDOR
+%left '&'
+%left EQ NEQ
+%left '<' '>' LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left '-' '+'
+%left POW
+%left '*' '/' '%' MPY
+%right '~' '!'
+%left '['
+%right CAST
+%right LOCNT BREV
+
+/* Bison Grammar */
+%%
+
+/* Input file containing the description of each hexagon instruction */
+input : instructions
+  {
+  YYACCEPT;
+  }
+  ;
+
+instructions : instruction instructions
+ | %empty
+ ;
+
+instruction : INAME
+  {
+  gen_inst(c, $1);
+  }
+  arguments
+  {
+  gen_inst_args(c, &@1);
+  }
+  code
+  {
+  gen_inst_code(c, &@1);
+  }
+| error /* Recover gracefully after instruction compilation error 
*/
+  {
+  free_instruction(c);
+  }
+;
+
+arguments : '(' ')'
+  | '(' argument_list ')';
+
+argument_list : decl ',' argument_list
+  | decl
+  ;
+
+var : VAR
+  {
+  track_string(c, $1.var.name);
+  $$ = $1;
+  }
+;
+
+/* Return the modified registers list */
+code : '{' statements '}'
+   

[PATCH v5 04/14] target/hexagon: make slot number an unsigned

2021-06-19 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Acked-by: Richard Henderson 
---
 target/hexagon/genptr.c | 6 --
 target/hexagon/macros.h | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 797a6c0cc9..3b8013d4e2 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -33,7 +33,8 @@ static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
 return pred;
 }
 
-static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot)
+static inline void gen_log_predicated_reg_write(int rnum, TCGv val,
+unsigned slot)
 {
 TCGv zero = tcg_const_tl(0);
 TCGv slot_mask = tcg_temp_new();
@@ -66,7 +67,8 @@ static inline void gen_log_reg_write(int rnum, TCGv val)
 }
 }
 
-static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int slot)
+static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val,
+  unsigned slot)
 {
 TCGv val32 = tcg_temp_new();
 TCGv zero = tcg_const_tl(0);
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index b726c3b791..eadb7e5d05 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -186,7 +186,7 @@
 #define LOAD_CANCEL(EA) do { CANCEL; } while (0)
 
 #ifdef QEMU_GENERATE
-static inline void gen_pred_cancel(TCGv pred, int slot_num)
+static inline void gen_pred_cancel(TCGv pred, unsigned slot_num)
  {
 TCGv slot_mask = tcg_const_tl(1 << slot_num);
 TCGv tmp = tcg_temp_new();
-- 
2.31.1




[PATCH v5 09/14] target/hexagon: import lexer for idef-parser

2021-06-19 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.h  | 262 
 target/hexagon/idef-parser/idef-parser.lex| 597 ++
 target/hexagon/meson.build|   4 +
 tests/docker/dockerfiles/alpine.docker|   1 +
 tests/docker/dockerfiles/centos8.docker   |   1 +
 tests/docker/dockerfiles/debian-amd64.docker  |   1 +
 tests/docker/dockerfiles/debian10.docker  |   1 +
 .../dockerfiles/fedora-i386-cross.docker  |   1 +
 .../dockerfiles/fedora-win32-cross.docker |   1 +
 .../dockerfiles/fedora-win64-cross.docker |   1 +
 tests/docker/dockerfiles/fedora.docker|   1 +
 tests/docker/dockerfiles/opensuse-leap.docker |   1 +
 tests/docker/dockerfiles/ubuntu.docker|   1 +
 tests/docker/dockerfiles/ubuntu1804.docker|   1 +
 tests/docker/dockerfiles/ubuntu2004.docker|   3 +-
 15 files changed, 876 insertions(+), 1 deletion(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.h
 create mode 100644 target/hexagon/idef-parser/idef-parser.lex

diff --git a/target/hexagon/idef-parser/idef-parser.h 
b/target/hexagon/idef-parser/idef-parser.h
new file mode 100644
index 00..d5feac8710
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef IDEF_PARSER_H
+#define IDEF_PARSER_H
+
+#include 
+#include 
+#include 
+#include 
+
+#define TCGV_NAME_SIZE 7
+#define MAX_WRITTEN_REGS 32
+#define OFFSET_STR_LEN 32
+#define ALLOC_LIST_LEN 32
+#define ALLOC_NAME_SIZE 32
+#define INIT_LIST_LEN 32
+#define OUT_BUF_LEN (1024 * 1024)
+#define SIGNATURE_BUF_LEN (128 * 1024)
+#define HEADER_BUF_LEN (128 * 1024)
+
+/* Variadic macros to wrap the buffer printing functions */
+#define EMIT(c, ...) \
+do { \
+g_string_append_printf((c)->out_str, __VA_ARGS__);   \
+} while (0)
+
+#define EMIT_SIG(c, ...)   
\
+do {   
\
+g_string_append_printf((c)->signature_str, __VA_ARGS__);   
\
+} while (0)
+
+#define EMIT_HEAD(c, ...)  
\
+do {   
\
+g_string_append_printf((c)->header_str, __VA_ARGS__);  
\
+} while (0)
+
+/**
+ * Type of register, assigned to the HexReg.type field
+ */
+typedef enum {GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW} RegType;
+
+/**
+ * Types of control registers, assigned to the HexReg.id field
+ */
+typedef enum {SP, FP, LR, GP, LC0, LC1, SA0, SA1} CregType;
+
+/**
+ * Identifier string of the control registers, indexed by the CregType enum
+ */
+extern const char *creg_str[];
+
+/**
+ * Semantic record of the REG tokens, identifying registers
+ */
+typedef struct HexReg {
+CregType id;/**< Identifier of the register  */
+RegType type;   /**< Type of the register*/
+unsigned bit_width; /**< Bit width of the reg, 32 or 64 bits */
+} HexReg;
+
+/**
+ * Data structure, identifying a TCGv temporary value
+ */
+typedef struct HexTmp {
+int index;  /**< Index of the TCGv temporary value*/
+} HexTmp;
+
+/**
+ * Enum of the possible immediated, an immediate is a value which is known
+ * at tinycode generation time, e.g. an integer value, not a TCGv
+ */
+enum ImmUnionTag {
+I,
+VARIABLE,
+VALUE,
+QEMU_TMP,
+IMM_PC,
+IMM_NPC,
+IMM_CONSTEXT,
+};
+
+/**
+ * Semantic record of the IMM token, identifying an immediate constant
+ */
+typedef struct HexImm {
+union {
+char id;/**< Identifier of the immediate */
+uint64_t value; /**< Immediate value (for VALUE type immediates) */
+uint64_t index; /**< Index of the immediate (for int temp vars)  */
+};
+enum ImmUnionTag type;  /**< Type of the immediate  */
+} HexImm;
+
+/**
+ * Semantic record of the PRE 

[PATCH v5 00/14] target/hexagon: introduce idef-parser

2021-06-19 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This patchset introduces the idef-parser for target/hexagon.

It's the fifth iteration of the patchset and includes fixes suggested in
previous iterations.

This patchset also drops some macro overrides that are no longer
necessary, since the instructions they were handling are now implemented
in `idef-parser`.

`idef-parser` is a build-time tool built using flex and bison. Its aim
is to generate a large part of the tiny code generator frontend for
Hexagon. The prototype of idef-parser has been presented at KVM Forum
2019 ("QEMU-Hexagon: Automatic Translation of the ISA Manual Pseudcode
to Tiny Code Instructions"):

https://www.youtube.com/watch?v=3EpnTYBOXCI

`target/hexagon/idef-parser/README.rst` provides an overview of the
parser and its inner working.

A couple of notes:

* `idef-parser` also supports certain things that are not used in the
  most recently submitted version of the "Hexagon patch
  series". However, they will be needed and stripping them out of the
  parser is quite a bit of work.
* The build on the CI fails for the cross-i386-* jobs. This seems to be
  due to the fact that, despite we specified glib as a native
  dependency, meson still chooses the i386 bit version of the library,
  as opposed to the x86-64.
  Help on this matter is appreciated.
  We also introduced a commit to make sure containers produced by the
  developer Docker registry (as opposed to the official one) is
  used. Otherwise, the changes we made to the containers would not
  take effect.
  Building debian-hexagon-cross still fails since it's not built by
  the CI by default.

Alessandro Di Federico (6):
  tcg: expose TCGCond manipulation routines
  target/hexagon: update MAINTAINERS for idef-parser
  target/hexagon: import README for idef-parser
  target/hexagon: prepare input for the idef-parser
  target/hexagon: call idef-parser functions
  gitlab-ci: do not use qemu-project Docker registry

Niccolò Izzo (2):
  target/hexagon: introduce new helper functions
  target/hexagon: import additional tests

Paolo Montesel (6):
  target/hexagon: make slot number an unsigned
  target/hexagon: make helper functions non-static
  target/hexagon: expose next PC in DisasContext
  target/hexagon: import lexer for idef-parser
  target/hexagon: import parser for idef-parser
  target/hexagon: remove unused macros and functions

 .gitlab-ci.d/container-cross.yml  |2 +-
 .gitlab-ci.d/container-template.yml   |4 +-
 MAINTAINERS   |8 +
 include/tcg/tcg-cond.h|  101 +
 include/tcg/tcg.h |   70 +-
 target/hexagon/README |5 +
 target/hexagon/gen_helper_funcs.py|5 +-
 target/hexagon/gen_helper_protos.py   |5 +-
 target/hexagon/gen_idef_parser_funcs.py   |  114 +
 target/hexagon/gen_tcg.h  |  528 
 target/hexagon/gen_tcg_funcs.py   |   28 +-
 target/hexagon/genptr.c   |  250 +-
 target/hexagon/genptr.h   |   29 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  447 +++
 target/hexagon/idef-parser/idef-parser.h  |  262 ++
 target/hexagon/idef-parser/idef-parser.lex|  597 
 target/hexagon/idef-parser/idef-parser.y  |  961 +++
 target/hexagon/idef-parser/macros.inc |  153 ++
 target/hexagon/idef-parser/parser-helpers.c   | 2396 +
 target/hexagon/idef-parser/parser-helpers.h   |  347 +++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/macros.h   |  209 +-
 target/hexagon/meson.build|  113 +-
 target/hexagon/op_helper.c|  119 -
 target/hexagon/translate.c|3 +-
 target/hexagon/translate.h|1 +
 tests/docker/dockerfiles/alpine.docker|2 +
 tests/docker/dockerfiles/centos8.docker   |2 +
 tests/docker/dockerfiles/debian-amd64.docker  |2 +
 tests/docker/dockerfiles/debian10.docker  |3 +
 .../dockerfiles/fedora-i386-cross.docker  |3 +
 .../dockerfiles/fedora-win32-cross.docker |3 +
 .../dockerfiles/fedora-win64-cross.docker |3 +
 tests/docker/dockerfiles/fedora.docker|2 +
 tests/docker/dockerfiles/opensuse-leap.docker |2 +
 tests/docker/dockerfiles/ubuntu.docker|3 +
 tests/docker/dockerfiles/ubuntu1804.docker|3 +
 tests/docker/dockerfiles/ubuntu2004.docker|5 +-
 tests/tcg/hexagon/Makefile.target |   36 +-
 tests/tcg/hexagon/crt.S   |   28 +
 tests/tcg/hexagon/test_abs.S  |   20 +
 tests/tcg/hexagon/test_add.S  |   20 +
 tests/tcg/hexagon/test_andp.S |   23 +
 tests/tcg/hexagon/test_bitcnt.S   |   42 +
 tests/tcg/hexagon/test_bitsplit.S |   25 

[PATCH v5 08/14] target/hexagon: prepare input for the idef-parser

2021-06-19 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Introduce infrastructure necessary to produce a file suitable for being
parsed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_idef_parser_funcs.py | 114 ++
 target/hexagon/idef-parser/macros.inc   | 153 
 target/hexagon/idef-parser/prepare  |  24 
 target/hexagon/meson.build  |  17 +++
 4 files changed, 308 insertions(+)
 create mode 100644 target/hexagon/gen_idef_parser_funcs.py
 create mode 100644 target/hexagon/idef-parser/macros.inc
 create mode 100755 target/hexagon/idef-parser/prepare

diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
new file mode 100644
index 00..7b8e0f6981
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+##
+##  This program 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.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, see .
+##
+
+import sys
+import re
+import string
+from io import StringIO
+
+import hex_common
+
+##
+## Generate code to be fed to the idef_parser
+##
+## Consider A2_add:
+##
+## Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
+##
+## We produce:
+##
+## A2_add(RdV, in RsV, in RtV) {
+##   { RdV=RsV+RtV;}
+## }
+##
+## A2_add represents the instruction tag. Then we have a list of TCGv
+## that the code generated by the parser can expect in input. Some of
+## them are inputs ("in" prefix), while some others are outputs.
+##
+def main():
+hex_common.read_semantics_file(sys.argv[1])
+hex_common.read_attribs_file(sys.argv[2])
+hex_common.read_overrides_file(sys.argv[3])
+hex_common.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[4], 'w') as f:
+f.write('#include "macros.inc"\n\n')
+
+for tag in hex_common.tags:
+## Skip the priv instructions
+if ( "A_PRIV" in hex_common.attribdict[tag] ) :
+continue
+## Skip the guest instructions
+if ( "A_GUEST" in hex_common.attribdict[tag] ) :
+continue
+## Skip instructions using switch
+if ( tag in {'S4_vrcrotate_acc', 'S4_vrcrotate'} ) :
+continue
+## Skip trap instructions
+if ( tag in {'J2_trap0', 'J2_trap1'} ) :
+continue
+## Skip 128-bit instructions
+if ( tag in {'A7_croundd_ri', 'A7_croundd_rr'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag.startswith('S2_cabacdecbin') ) :
+continue
+if ( tag.startswith('Y') ) :
+continue
+if ( tag.startswith('V6_') ) :
+continue
+if ( tag.startswith('F') ) :
+continue
+if ( tag.endswith('_locked') ) :
+continue
+
+regs = tagregs[tag]
+imms = tagimms[tag]
+
+arguments = []
+if hex_common.need_ea(tag):
+arguments.append("EA")
+
+for regtype,regid,toss,numregs in regs:
+prefix = "in " if hex_common.is_read(regid) else ""
+
+is_pair = hex_common.is_pair(regid)
+is_single_old = (hex_common.is_single(regid)
+ and hex_common.is_old_val(regtype, regid, 
tag))
+is_single_new = (hex_common.is_single(regid)
+ and hex_common.is_new_val(regtype, regid, 
tag))
+
+if is_pair or is_single_old:
+arguments.append("%s%s%sV" % (prefix, regtype, regid))
+elif is_single_new:
+arguments.append("%s%s%sN" % (prefix, regtype, regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+for immlett,bits,immshift in imms:
+arguments.append(hex_common.imm_name(immlett))
+
+f.write("%s(%s) {\n" % (tag, ", ".join(arguments)))
+f.write("%s\n" % hex_common.semdict[tag])
+f.write("}\n\n")
+
+if __name__ == "__main__":
+main()
diff --git a/target/hexagon/idef-parser/macros.inc 
b/target/hexagon/idef-parser/macros.inc
new

[PATCH v5 07/14] target/hexagon: expose next PC in DisasContext

2021-06-19 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Reviewed-by: Richard Henderson 
---
 target/hexagon/translate.c | 3 ++-
 target/hexagon/translate.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 9a37644182..34c3bc5222 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -516,11 +516,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, &pkt, false) > 0) {
 HEX_DEBUG_PRINT_PKT(&pkt);
 gen_start_packet(ctx, &pkt);
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, &pkt.insn[i], &pkt);
 }
 gen_commit_packet(ctx, &pkt);
-ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
+ctx->base.pc_next = ctx->npc;
 } else {
 gen_exception_end_tb(ctx, HEX_EXCP_INVALID_PACKET);
 }
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 703fd1345f..d5a7fece31 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -37,6 +37,7 @@ typedef struct DisasContext {
 DECLARE_BITMAP(pregs_written, NUM_PREGS);
 uint8_t store_width[STORES_MAX];
 bool s1_store_processed;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.31.1




[PATCH v5 06/14] target/hexagon: introduce new helper functions

2021-06-19 Thread Alessandro Di Federico via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 target/hexagon/genptr.c | 163 
 target/hexagon/genptr.h |  23 ++
 target/hexagon/macros.h |   9 +++
 3 files changed, 180 insertions(+), 15 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 6f2816f6e2..cf45c28f58 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -28,6 +28,12 @@
 #include "gen_tcg.h"
 #include "genptr.h"
 
+TCGv gen_read_reg(TCGv result, int num)
+{
+tcg_gen_mov_tl(result, hex_gpr[num]);
+return result;
+}
+
 TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
@@ -396,18 +402,19 @@ static inline void gen_store_conditional8(CPUHexagonState 
*env,
 tcg_gen_movi_tl(hex_llsc_addr, ~0);
 }
 
-static inline void gen_store32(TCGv vaddr, TCGv src, int width, int slot)
+void gen_store32(DisasContext *ctx, TCGv vaddr, TCGv src, tcg_target_long 
width,
+ unsigned slot)
 {
 tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
 tcg_gen_movi_tl(hex_store_width[slot], width);
 tcg_gen_mov_tl(hex_store_val32[slot], src);
+ctx->store_width[slot] = width;
 }
 
-static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, int slot)
+void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
 {
-gen_store32(vaddr, src, 1, slot);
-ctx->store_width[slot] = 1;
+gen_store32(ctx, vaddr, src, 1, slot);
 }
 
 static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
@@ -418,11 +425,10 @@ static inline void gen_store1i(TCGv_env cpu_env, TCGv 
vaddr, int32_t src,
 tcg_temp_free(tmp);
 }
 
-static inline void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, int slot)
+void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
 {
-gen_store32(vaddr, src, 2, slot);
-ctx->store_width[slot] = 2;
+gen_store32(ctx, vaddr, src, 2, slot);
 }
 
 static inline void gen_store2i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
@@ -433,11 +439,10 @@ static inline void gen_store2i(TCGv_env cpu_env, TCGv 
vaddr, int32_t src,
 tcg_temp_free(tmp);
 }
 
-static inline void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, int slot)
+void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
 {
-gen_store32(vaddr, src, 4, slot);
-ctx->store_width[slot] = 4;
+gen_store32(ctx, vaddr, src, 4, slot);
 }
 
 static inline void gen_store4i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
@@ -448,8 +453,8 @@ static inline void gen_store4i(TCGv_env cpu_env, TCGv 
vaddr, int32_t src,
 tcg_temp_free(tmp);
 }
 
-static inline void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src,
-  DisasContext *ctx, int slot)
+void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, DisasContext *ctx,
+unsigned slot)
 {
 tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
 tcg_gen_movi_tl(hex_store_width[slot], 8);
@@ -476,5 +481,133 @@ static TCGv gen_8bitsof(TCGv result, TCGv value)
 return result;
 }
 
+void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_gpr[HEX_REG_USR], hex_gpr[HEX_REG_USR], val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+}
+
+void gen_set_usr_fieldi(int field, int x)
+{
+TCGv val = tcg_const_tl(x);
+gen_set_usr_field(field, val);
+tcg_temp_free(val);
+}
+
+void gen_write_new_pc(TCGv addr)
+{
+/* If there are multiple branches in a packet, ignore the second one */
+TCGv zero = tcg_const_tl(0);
+tcg_gen_movcond_tl(TCG_COND_NE, hex_next_PC, hex_branch_taken, zero,
+   hex_next_PC, addr);
+tcg_gen_movi_tl(hex_branch_taken, 1);
+tcg_temp_free(zero);
+}
+
+void gen_sat_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_const_i32((1 << (width - 1)) - 1);
+TCGv min_val = tcg_const_i32(-(1 << (width - 1)));
+tcg_gen_smin_tl(dest, source, max_val);
+tcg_gen_smax_tl(dest, dest, min_val);
+tcg_temp_free_i32(max_val);
+tcg_temp_free_i32(min_val);
+}
+
+void gen_sat_i32_ext(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_sat_i32(dest, source, width);
+tcg_gen_setcond_i32(TCG_COND_NE, ovfl, source, dest);
+}
+
+void gen_satu_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_const_i32((1 << width) - 1);
+tcg_gen_movcond_i32(TCG_COND_GTU, dest, source, max_val, max_val, source);
+TCGv_i32 zero = tcg_const_i32(0);
+tcg_gen_movcond_i32(TCG_COND_LT, dest, source, zero, zero, dest);
+tcg_temp_free_i32(max_val);
+  

[PATCH v5 01/14] tcg: expose TCGCond manipulation routines

2021-06-19 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This commit moves into a separate file routines used to manipulate
TCGCond. These will be employed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 include/tcg/tcg-cond.h | 101 +
 include/tcg/tcg.h  |  70 +---
 2 files changed, 102 insertions(+), 69 deletions(-)
 create mode 100644 include/tcg/tcg-cond.h

diff --git a/include/tcg/tcg-cond.h b/include/tcg/tcg-cond.h
new file mode 100644
index 00..2a38a386d4
--- /dev/null
+++ b/include/tcg/tcg-cond.h
@@ -0,0 +1,101 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef TCG_COND_H
+#define TCG_COND_H
+
+/*
+ * Conditions.  Note that these are laid out for easy manipulation by
+ * the functions below:
+ *bit 0 is used for inverting;
+ *bit 1 is signed,
+ *bit 2 is unsigned,
+ *bit 3 is used with bit 0 for swapping signed/unsigned.
+ */
+typedef enum {
+/* non-signed */
+TCG_COND_NEVER  = 0 | 0 | 0 | 0,
+TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
+TCG_COND_EQ = 8 | 0 | 0 | 0,
+TCG_COND_NE = 8 | 0 | 0 | 1,
+/* signed */
+TCG_COND_LT = 0 | 0 | 2 | 0,
+TCG_COND_GE = 0 | 0 | 2 | 1,
+TCG_COND_LE = 8 | 0 | 2 | 0,
+TCG_COND_GT = 8 | 0 | 2 | 1,
+/* unsigned */
+TCG_COND_LTU= 0 | 4 | 0 | 0,
+TCG_COND_GEU= 0 | 4 | 0 | 1,
+TCG_COND_LEU= 8 | 4 | 0 | 0,
+TCG_COND_GTU= 8 | 4 | 0 | 1,
+} TCGCond;
+
+/* Invert the sense of the comparison.  */
+static inline TCGCond tcg_invert_cond(TCGCond c)
+{
+return (TCGCond)(c ^ 1);
+}
+
+/* Swap the operands in a comparison.  */
+static inline TCGCond tcg_swap_cond(TCGCond c)
+{
+return c & 6 ? (TCGCond)(c ^ 9) : c;
+}
+
+/* Create an "unsigned" version of a "signed" comparison.  */
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
+{
+return c & 2 ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Create a "signed" version of an "unsigned" comparison.  */
+static inline TCGCond tcg_signed_cond(TCGCond c)
+{
+return c & 4 ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Must a comparison be considered unsigned?  */
+static inline bool is_unsigned_cond(TCGCond c)
+{
+return (c & 4) != 0;
+}
+
+/*
+ * Create a "high" version of a double-word comparison.
+ * This removes equality from a LTE or GTE comparison.
+ */
+static inline TCGCond tcg_high_cond(TCGCond c)
+{
+switch (c) {
+case TCG_COND_GE:
+case TCG_COND_LE:
+case TCG_COND_GEU:
+case TCG_COND_LEU:
+return (TCGCond)(c ^ 8);
+default:
+return c;
+}
+}
+
+#endif /* TCG_COND_H */
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 064dab383b..23a49122da 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -33,6 +33,7 @@
 #include "tcg/tcg-mo.h"
 #include "tcg-target.h"
 #include "qemu/int128.h"
+#include "tcg/tcg-cond.h"
 
 /* XXX: make safe guess about sizes */
 #define MAX_OP_PER_INSTR 266
@@ -406,75 +407,6 @@ typedef TCGv_ptr TCGv_env;
 /* Used to align parameters.  See the comment before tcgv_i32_temp.  */
 #define TCG_CALL_DUMMY_ARG  ((TCGArg)0)
 
-/* Conditions.  Note that these are laid out for easy manipulation by
-   the functions below:
- bit 0 is used for inverting;
- bit 1 is signed,
- bit 2 is unsigned,
- bit 3 is used with bit 0 for swapping signed/unsigned.  */
-typedef enum {
-/* non-signed */
-TCG_COND_NEVER  = 0 | 0 | 0 | 0,
-TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
-TCG_COND_EQ = 8 | 0 | 0 | 0,
-TCG_COND_NE = 8 | 0 | 0 | 1,
-/* signed */
-TCG_COND_LT = 0 | 0 | 2 | 0,
-TCG_COND_GE = 0 | 0 | 2 | 1,
-TCG_COND_LE = 8 | 0 | 2 | 0,
-TCG_COND_GT = 8 | 0 | 2 | 1,
-/* unsigned */
-TCG_COND_LTU= 0 | 4 | 0 | 0,
-TCG_COND_GEU= 0 | 4 | 0 | 1,
-TCG_COND_LEU= 8 | 4 | 0 

Re: [PATCH v4 06/12] target/hexagon: introduce new helper functions

2021-04-19 Thread Alessandro Di Federico via
On Mon, 19 Apr 2021 15:00:17 +
Taylor Simpson  wrote:

> Once this patch series is merged, many load/store instructions will
> have manual overrides.  I can easily provide overrides for the
> remainder.  Then, we could skip them in the idef-parser.  At a
> minimum, you should skip the ones that are part of that series
> - circular addressing
> https://lists.gnu.org/archive/html/qemu-devel/2021-04/msg01355.html
> - bit reverse addressing
> https://lists.gnu.org/archive/html/qemu-devel/2021-04/msg01354.html
> - load and unpack bytes
> https://lists.gnu.org/archive/html/qemu-devel/2021-04/msg01353.html
>   
> - load into shifted register
> https://lists.gnu.org/archive/html/qemu-devel/2021-04/msg01359.html
> 
> Alessandro, what do you think?

If, for an instruction, all idef-parse does is calling an helper, yeah,
it makes sense to exclude them.

I'll look into this again once your patchset is in.

-- 
Alessandro Di Federico
rev.ng



[PATCH v4 07/12] target/hexagon: expose next PC in DisasContext

2021-04-15 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/translate.c | 3 ++-
 target/hexagon/translate.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index eeaad5f8ba..30ff3c5d51 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -503,11 +503,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, &pkt, false) > 0) {
 HEX_DEBUG_PRINT_PKT(&pkt);
 gen_start_packet(ctx, &pkt);
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, &pkt.insn[i], &pkt);
 }
 gen_commit_packet(ctx, &pkt);
-ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
+ctx->base.pc_next = ctx->npc;
 } else {
 gen_exception(HEX_EXCP_INVALID_PACKET);
 ctx->base.is_jmp = DISAS_NORETURN;
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 938f7fbb9f..2195e20f4b 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -36,6 +36,7 @@ typedef struct DisasContext {
 int preg_log_idx;
 uint8_t store_width[STORES_MAX];
 uint8_t s1_store_processed;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.31.1




[PATCH v4 01/12] tcg: expose TCGCond manipulation routines

2021-04-15 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This commit moves into a separate file routines used to manipulate
TCGCond. These will be employed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 include/tcg/tcg-cond.h | 101 +
 include/tcg/tcg.h  |  70 +---
 2 files changed, 102 insertions(+), 69 deletions(-)
 create mode 100644 include/tcg/tcg-cond.h

diff --git a/include/tcg/tcg-cond.h b/include/tcg/tcg-cond.h
new file mode 100644
index 00..2a38a386d4
--- /dev/null
+++ b/include/tcg/tcg-cond.h
@@ -0,0 +1,101 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef TCG_COND_H
+#define TCG_COND_H
+
+/*
+ * Conditions.  Note that these are laid out for easy manipulation by
+ * the functions below:
+ *bit 0 is used for inverting;
+ *bit 1 is signed,
+ *bit 2 is unsigned,
+ *bit 3 is used with bit 0 for swapping signed/unsigned.
+ */
+typedef enum {
+/* non-signed */
+TCG_COND_NEVER  = 0 | 0 | 0 | 0,
+TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
+TCG_COND_EQ = 8 | 0 | 0 | 0,
+TCG_COND_NE = 8 | 0 | 0 | 1,
+/* signed */
+TCG_COND_LT = 0 | 0 | 2 | 0,
+TCG_COND_GE = 0 | 0 | 2 | 1,
+TCG_COND_LE = 8 | 0 | 2 | 0,
+TCG_COND_GT = 8 | 0 | 2 | 1,
+/* unsigned */
+TCG_COND_LTU= 0 | 4 | 0 | 0,
+TCG_COND_GEU= 0 | 4 | 0 | 1,
+TCG_COND_LEU= 8 | 4 | 0 | 0,
+TCG_COND_GTU= 8 | 4 | 0 | 1,
+} TCGCond;
+
+/* Invert the sense of the comparison.  */
+static inline TCGCond tcg_invert_cond(TCGCond c)
+{
+return (TCGCond)(c ^ 1);
+}
+
+/* Swap the operands in a comparison.  */
+static inline TCGCond tcg_swap_cond(TCGCond c)
+{
+return c & 6 ? (TCGCond)(c ^ 9) : c;
+}
+
+/* Create an "unsigned" version of a "signed" comparison.  */
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
+{
+return c & 2 ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Create a "signed" version of an "unsigned" comparison.  */
+static inline TCGCond tcg_signed_cond(TCGCond c)
+{
+return c & 4 ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Must a comparison be considered unsigned?  */
+static inline bool is_unsigned_cond(TCGCond c)
+{
+return (c & 4) != 0;
+}
+
+/*
+ * Create a "high" version of a double-word comparison.
+ * This removes equality from a LTE or GTE comparison.
+ */
+static inline TCGCond tcg_high_cond(TCGCond c)
+{
+switch (c) {
+case TCG_COND_GE:
+case TCG_COND_LE:
+case TCG_COND_GEU:
+case TCG_COND_LEU:
+return (TCGCond)(c ^ 8);
+default:
+return c;
+}
+}
+
+#endif /* TCG_COND_H */
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 0f0695e90d..3dc468ebd8 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -34,6 +34,7 @@
 #include "tcg/tcg-mo.h"
 #include "tcg-target.h"
 #include "qemu/int128.h"
+#include "tcg/tcg-cond.h"
 
 /* XXX: make safe guess about sizes */
 #define MAX_OP_PER_INSTR 266
@@ -407,75 +408,6 @@ typedef TCGv_ptr TCGv_env;
 /* Used to align parameters.  See the comment before tcgv_i32_temp.  */
 #define TCG_CALL_DUMMY_ARG  ((TCGArg)0)
 
-/* Conditions.  Note that these are laid out for easy manipulation by
-   the functions below:
- bit 0 is used for inverting;
- bit 1 is signed,
- bit 2 is unsigned,
- bit 3 is used with bit 0 for swapping signed/unsigned.  */
-typedef enum {
-/* non-signed */
-TCG_COND_NEVER  = 0 | 0 | 0 | 0,
-TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
-TCG_COND_EQ = 8 | 0 | 0 | 0,
-TCG_COND_NE = 8 | 0 | 0 | 1,
-/* signed */
-TCG_COND_LT = 0 | 0 | 2 | 0,
-TCG_COND_GE = 0 | 0 | 2 | 1,
-TCG_COND_LE = 8 | 0 | 2 | 0,
-TCG_COND_GT = 8 | 0 | 2 | 1,
-/* unsigned */
-TCG_COND_LTU= 0 | 4 | 0 | 0,
-TCG_COND_GEU= 0 | 4 | 0 | 1,
-TCG_COND_LEU= 8 | 4 | 0 

[PATCH v4 04/12] target/hexagon: make slot number an unsigned

2021-04-15 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/genptr.c | 6 --
 target/hexagon/macros.h | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 7481f4c1dd..fd18aabe8d 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -33,7 +33,8 @@ static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
 return pred;
 }
 
-static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot)
+static inline void gen_log_predicated_reg_write(int rnum, TCGv val,
+unsigned slot)
 {
 TCGv one = tcg_const_tl(1);
 TCGv zero = tcg_const_tl(0);
@@ -62,7 +63,8 @@ static inline void gen_log_reg_write(int rnum, TCGv val)
 #endif
 }
 
-static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int slot)
+static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val,
+  unsigned slot)
 {
 TCGv val32 = tcg_temp_new();
 TCGv one = tcg_const_tl(1);
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index cfcb8173ba..d9473c8823 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -154,7 +154,7 @@
 #define LOAD_CANCEL(EA) do { CANCEL; } while (0)
 
 #ifdef QEMU_GENERATE
-static inline void gen_pred_cancel(TCGv pred, int slot_num)
+static inline void gen_pred_cancel(TCGv pred, unsigned slot_num)
  {
 TCGv slot_mask = tcg_const_tl(1 << slot_num);
 TCGv tmp = tcg_temp_new();
-- 
2.31.1




[PATCH v4 02/12] target/hexagon: update MAINTAINERS for idef-parser

2021-04-15 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 36055f14c5..158badbd18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -193,11 +193,19 @@ Hexagon TCG CPUs
 M: Taylor Simpson 
 S: Supported
 F: target/hexagon/
+X: target/hexagon/idef-parser/
+X: target/hexagon/gen_idef_parser_funcs.py
 F: linux-user/hexagon/
 F: tests/tcg/hexagon/
 F: disas/hexagon.c
 F: default-configs/targets/hexagon-linux-user.mak
 
+Hexagon idef-parser
+M: Alessandro Di Federico 
+S: Supported
+F: target/hexagon/idef-parser/
+F: target/hexagon/gen_idef_parser_funcs.py
+
 HPPA (PA-RISC) TCG CPUs
 M: Richard Henderson 
 S: Maintained
-- 
2.31.1




[PATCH v4 11/12] target/hexagon: call idef-parser functions

2021-04-15 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Extend gen_tcg_funcs.py in order to emit calls to the functions emitted
by the idef-parser, if available.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_tcg_funcs.py | 28 ++--
 target/hexagon/hex_common.py| 10 ++
 target/hexagon/meson.build  | 22 +-
 3 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index db9f663a77..5980dab8ee 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -394,7 +394,29 @@ def gen_tcg_func(f, tag, regs, imms):
 if (hex_common.is_read(regid)):
 genptr_src_read_opn(f,regtype,regid,tag)
 
-if ( hex_common.skip_qemu_helper(tag) ):
+if hex_common.is_idef_parser_enabled(tag):
+declared = []
+## Handle registers
+for regtype,regid,toss,numregs in regs:
+if (hex_common.is_pair(regid)
+or (hex_common.is_single(regid)
+and hex_common.is_old_val(regtype, regid, tag))):
+declared.append("%s%sV" % (regtype, regid))
+if regtype == "M":
+declared.append("%s%sN" % (regtype, regid))
+elif hex_common.is_new_val(regtype, regid, tag):
+declared.append("%s%sN" % (regtype,regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+## Handle immediates
+for immlett,bits,immshift in imms:
+declared.append(hex_common.imm_name(immlett))
+
+arguments = ", ".join(["ctx", "insn", "pkt"] + declared)
+f.write("emit_%s(%s);\n" % (tag, arguments))
+
+elif ( hex_common.skip_qemu_helper(tag) ):
 f.write("fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
 else:
 ## Generate the call to the helper
@@ -455,12 +477,14 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.calculate_attribs()
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
 f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
+f.write("#include \"idef-generated-emitter.h.inc\"\n\n")
 
 for tag in hex_common.tags:
 ## Skip the priv instructions
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index b3b534057d..648ad29e94 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -28,6 +28,7 @@
 attribinfo = {}   # Register information and misc
 tags = [] # list of all tags
 overrides = {}# tags with helper overrides
+idef_parser_enabled = {} # tags enabled for idef-parser
 
 # We should do this as a hash for performance,
 # but to keep order let's keep it as a list.
@@ -201,6 +202,9 @@ def need_ea(tag):
 def skip_qemu_helper(tag):
 return tag in overrides.keys()
 
+def is_idef_parser_enabled(tag):
+return tag in idef_parser_enabled
+
 def imm_name(immlett):
 return "%siV" % immlett
 
@@ -232,3 +236,9 @@ def read_overrides_file(name):
 continue
 tag = overridere.findall(line)[0]
 overrides[tag] = True
+
+def read_idef_parser_enabled_file(name):
+global idef_parser_enabled
+with open(name, "r") as idef_parser_enabled_file:
+lines = idef_parser_enabled_file.read().strip().split("\n")
+idef_parser_enabled = set(lines)
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index abd931d636..7f30237e59 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -69,15 +69,6 @@ helper_protos_generated = custom_target(
 )
 hexagon_ss.add(helper_protos_generated)
 
-tcg_funcs_generated = custom_target(
-'tcg_funcs_generated.c.inc',
-output: 'tcg_funcs_generated.c.inc',
-depends: [semantics_generated],
-depend_files: [hex_common_py, attribs_def, gen_tcg_h],
-command: [python, files('gen_tcg_funcs.py'), semantics_generated, 
attribs_def, gen_tcg_h, '@OUTPUT@'],
-)
-hexagon_ss.add(tcg_funcs_generated)
-
 tcg_func_table_generated = custom_target(
 'tcg_func_table_generated.c.inc',
 output: 'tcg_func_table_generated.c.inc',
@@ -221,4 +212,17 @@ idef_generated_tcg = custom_target(
 command: [idef_parser, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@', '@OUTPUT2@'],
 )
 
+idef_generated_list = idef_generated_tcg[2].full_path()
+
+hexagon_ss.add(idef_generated_tcg)
+
+tcg_funcs_generated = custom_target(
+'tcg_funcs_generated.c.inc',
+output: 'tcg_funcs_generated.c.inc',
+depends: [semantics_generated, idef_generated_tcg],
+depend_files: [hex_common_py, attribs_def, gen_tcg_h],
+command: [python, files('gen_tcg_funcs.py'), semantics_generated,

[PATCH v4 10/12] target/hexagon: import parser for idef-parser

2021-04-15 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.y  |  947 +++
 target/hexagon/idef-parser/parser-helpers.c   | 2374 +
 target/hexagon/idef-parser/parser-helpers.h   |  347 +++
 target/hexagon/meson.build|   26 +-
 tests/docker/dockerfiles/alpine.docker|1 +
 tests/docker/dockerfiles/centos7.docker   |1 +
 tests/docker/dockerfiles/centos8.docker   |1 +
 tests/docker/dockerfiles/debian10.docker  |2 +
 .../dockerfiles/fedora-i386-cross.docker  |2 +
 .../dockerfiles/fedora-win32-cross.docker |2 +
 .../dockerfiles/fedora-win64-cross.docker |2 +
 tests/docker/dockerfiles/fedora.docker|1 +
 tests/docker/dockerfiles/opensuse-leap.docker |1 +
 tests/docker/dockerfiles/ubuntu.docker|2 +
 tests/docker/dockerfiles/ubuntu1804.docker|2 +
 tests/docker/dockerfiles/ubuntu2004.docker|4 +-
 16 files changed, 3713 insertions(+), 2 deletions(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.y
 create mode 100644 target/hexagon/idef-parser/parser-helpers.c
 create mode 100644 target/hexagon/idef-parser/parser-helpers.h

diff --git a/target/hexagon/idef-parser/idef-parser.y 
b/target/hexagon/idef-parser/idef-parser.y
new file mode 100644
index 00..dbfc9572f9
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,947 @@
+%{
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "idef-parser.h"
+#include "parser-helpers.h"
+#include "idef-parser.tab.h"
+#include "idef-parser.yy.h"
+
+/* Uncomment this to disable yyasserts */
+/* #define NDEBUG */
+
+#define ERR_LINE_CONTEXT 40
+
+%}
+
+%lex-param {void *scanner}
+%parse-param {void *scanner}
+%parse-param {Context *c}
+
+%define parse.error verbose
+%define parse.lac full
+%define api.pure full
+
+%locations
+
+%union {
+GString *string;
+HexValue rvalue;
+HexSat sat;
+HexCast cast;
+HexExtract extract;
+HexMpy mpy;
+bool is_unsigned;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token INAME DREG DIMM DPRE DEA RREG WREG FREG FIMM RPRE WPRE FPRE FWRAP FEA 
VAR
+%token POW ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS 
ASL
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL ORL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE CONSTLL CONSTULL PC NPC LPCFG
+%token CANCEL IDENTITY PART1 BREV_4 BREV_8 ROTL INSBITS SETBITS EXTBITS 
EXTRANGE
+%token CAST4_8U SETOVF FAIL DEINTERLEAVE INTERLEAVE CARRY_FROM_ADD
+
+%token  REG IMM PRE
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement var
+%type  DREG DIMM DPRE RREG RPRE FAIL
+%type  if_stmt IF
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left '('
+%left ','
+%left '='
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left '?' ':'
+%left ORL
+%left ANDL
+%left '|'
+%left '^' ANDOR
+%left '&'
+%left EQ NEQ
+%left '<' '>' LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left '-' '+'
+%left POW
+%left '*' '/' '%' MPY
+%right '~' '!'
+%left '['
+%right CAST
+%right LOCNT BREV
+
+/* Bison Grammar */
+%%
+
+/* Input file containing the description of each hexagon instruction */
+input : instructions
+  {
+  YYACCEPT;
+  }
+  ;
+
+instructions : instruction instructions
+ | %empty
+ ;
+
+instruction : INAME
+  {
+  gen_inst(c, $1);
+  }
+  arguments
+  {
+  gen_inst_args(c, &@1);
+  }
+  code
+  {
+  gen_inst_code(c, &@1);
+  }
+| error /* Recover gracefully after instruction compilation error 
*/
+  {
+  free_instruction(c);
+  }
+;
+
+arguments : '(' ')'
+  | '(' argument_list ')';
+
+argument_list : decl ',' argument_list
+  | decl
+  ;
+
+var : VAR
+  {
+  track_string(c, $1.var.name);
+  $$ = $1;
+  }
+;
+
+/* Return the modified registers list */
+code : '{' statements '}'
+   {
+

[PATCH v4 09/12] target/hexagon: import lexer for idef-parser

2021-04-15 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.h  | 254 
 target/hexagon/idef-parser/idef-parser.lex| 611 ++
 target/hexagon/meson.build|   4 +
 tests/docker/dockerfiles/alpine.docker|   1 +
 tests/docker/dockerfiles/centos7.docker   |   1 +
 tests/docker/dockerfiles/centos8.docker   |   1 +
 tests/docker/dockerfiles/debian10.docker  |   1 +
 .../dockerfiles/fedora-i386-cross.docker  |   1 +
 .../dockerfiles/fedora-win32-cross.docker |   1 +
 .../dockerfiles/fedora-win64-cross.docker |   1 +
 tests/docker/dockerfiles/fedora.docker|   1 +
 tests/docker/dockerfiles/opensuse-leap.docker |   1 +
 tests/docker/dockerfiles/ubuntu.docker|   1 +
 tests/docker/dockerfiles/ubuntu1804.docker|   1 +
 tests/docker/dockerfiles/ubuntu2004.docker|   3 +-
 15 files changed, 882 insertions(+), 1 deletion(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.h
 create mode 100644 target/hexagon/idef-parser/idef-parser.lex

diff --git a/target/hexagon/idef-parser/idef-parser.h 
b/target/hexagon/idef-parser/idef-parser.h
new file mode 100644
index 00..f9aaff71f6
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef IDEF_PARSER_H
+#define IDEF_PARSER_H
+
+#include 
+#include 
+#include 
+#include 
+
+#define TCGV_NAME_SIZE 7
+#define MAX_WRITTEN_REGS 32
+#define OFFSET_STR_LEN 32
+#define ALLOC_LIST_LEN 32
+#define ALLOC_NAME_SIZE 32
+#define INIT_LIST_LEN 32
+#define OUT_BUF_LEN (1024 * 1024)
+#define SIGNATURE_BUF_LEN (128 * 1024)
+#define HEADER_BUF_LEN (128 * 1024)
+
+/* Variadic macros to wrap the buffer printing functions */
+#define EMIT(c, ...) \
+do { \
+g_string_append_printf((c)->out_str, __VA_ARGS__);   \
+} while (0)
+
+#define EMIT_SIG(c, ...)   
\
+do {   
\
+g_string_append_printf((c)->signature_str, __VA_ARGS__);   
\
+} while (0)
+
+#define EMIT_HEAD(c, ...)  
\
+do {   
\
+g_string_append_printf((c)->header_str, __VA_ARGS__);  
\
+} while (0)
+
+/**
+ * Type of register, assigned to the HexReg.type field
+ */
+typedef enum {GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW} RegType;
+
+/**
+ * Types of control registers, assigned to the HexReg.id field
+ */
+typedef enum {SP, FP, LR, GP, LC0, LC1, SA0, SA1} CregType;
+
+/**
+ * Identifier string of the control registers, indexed by the CregType enum
+ */
+extern const char *creg_str[];
+
+/**
+ * Semantic record of the REG tokens, identifying registers
+ */
+typedef struct HexReg {
+CregType id;/**< Identifier of the register  */
+RegType type;   /**< Type of the register*/
+unsigned bit_width; /**< Bit width of the reg, 32 or 64 bits */
+} HexReg;
+
+/**
+ * Data structure, identifying a TCGv temporary value
+ */
+typedef struct HexTmp {
+int index;  /**< Index of the TCGv temporary value*/
+} HexTmp;
+
+/**
+ * Enum of the possible immediated, an immediate is a value which is known
+ * at tinycode generation time, e.g. an integer value, not a TCGv
+ */
+enum ImmUnionTag {I, VARIABLE, VALUE, QEMU_TMP, IMM_PC, IMM_CONSTEXT};
+
+/**
+ * Semantic record of the IMM token, identifying an immediate constant
+ */
+typedef struct HexImm {
+union {
+char id;/**< Identifier of the immediate */
+uint64_t value; /**< Immediate value (for VALUE type immediates) */
+uint64_t index; /**< Index of the immediate (for int temp vars)  */
+};
+enum ImmUnionTag type;  /**< Type of the immediate  */
+} HexImm;
+
+/**
+ * Semantic record of the PRE token, identifying a predicate
+ */
+typedef str

[PATCH v4 12/12] target/hexagon: import additional tests

2021-04-15 Thread Alessandro Di Federico via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 tests/tcg/hexagon/Makefile.target  | 36 -
 tests/tcg/hexagon/crt.S| 28 +
 tests/tcg/hexagon/test_abs.S   | 20 ++
 tests/tcg/hexagon/test_add.S   | 20 ++
 tests/tcg/hexagon/test_andp.S  | 23 +++
 tests/tcg/hexagon/test_bitcnt.S| 42 
 tests/tcg/hexagon/test_bitsplit.S  | 25 
 tests/tcg/hexagon/test_call.S  | 63 ++
 tests/tcg/hexagon/test_clobber.S   | 35 +
 tests/tcg/hexagon/test_cmp.S   | 34 
 tests/tcg/hexagon/test_cmpy.S  | 31 +++
 tests/tcg/hexagon/test_djump.S | 24 
 tests/tcg/hexagon/test_dotnew.S| 39 ++
 tests/tcg/hexagon/test_dstore.S| 29 ++
 tests/tcg/hexagon/test_ext.S   | 18 +
 tests/tcg/hexagon/test_fibonacci.S | 33 
 tests/tcg/hexagon/test_hello.S | 21 ++
 tests/tcg/hexagon/test_hl.S| 19 +
 tests/tcg/hexagon/test_hwloops.S   | 25 
 tests/tcg/hexagon/test_jmp.S   | 25 
 tests/tcg/hexagon/test_lsr.S   | 39 ++
 tests/tcg/hexagon/test_mpyi.S  | 20 ++
 tests/tcg/hexagon/test_overflow.S  | 63 ++
 tests/tcg/hexagon/test_packet.S| 26 
 tests/tcg/hexagon/test_reorder.S   | 31 +++
 tests/tcg/hexagon/test_round.S | 31 +++
 tests/tcg/hexagon/test_vavgw.S | 33 
 tests/tcg/hexagon/test_vcmpb.S | 32 +++
 tests/tcg/hexagon/test_vcmpw.S | 29 ++
 tests/tcg/hexagon/test_vcmpy.S | 50 
 tests/tcg/hexagon/test_vlsrw.S | 23 +++
 tests/tcg/hexagon/test_vmaxh.S | 37 ++
 tests/tcg/hexagon/test_vminh.S | 37 ++
 tests/tcg/hexagon/test_vpmpyh.S| 30 ++
 tests/tcg/hexagon/test_vspliceb.S  | 33 
 35 files changed, 1103 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/hexagon/crt.S
 create mode 100644 tests/tcg/hexagon/test_abs.S
 create mode 100644 tests/tcg/hexagon/test_add.S
 create mode 100644 tests/tcg/hexagon/test_andp.S
 create mode 100644 tests/tcg/hexagon/test_bitcnt.S
 create mode 100644 tests/tcg/hexagon/test_bitsplit.S
 create mode 100644 tests/tcg/hexagon/test_call.S
 create mode 100644 tests/tcg/hexagon/test_clobber.S
 create mode 100644 tests/tcg/hexagon/test_cmp.S
 create mode 100644 tests/tcg/hexagon/test_cmpy.S
 create mode 100644 tests/tcg/hexagon/test_djump.S
 create mode 100644 tests/tcg/hexagon/test_dotnew.S
 create mode 100644 tests/tcg/hexagon/test_dstore.S
 create mode 100644 tests/tcg/hexagon/test_ext.S
 create mode 100644 tests/tcg/hexagon/test_fibonacci.S
 create mode 100644 tests/tcg/hexagon/test_hello.S
 create mode 100644 tests/tcg/hexagon/test_hl.S
 create mode 100644 tests/tcg/hexagon/test_hwloops.S
 create mode 100644 tests/tcg/hexagon/test_jmp.S
 create mode 100644 tests/tcg/hexagon/test_lsr.S
 create mode 100644 tests/tcg/hexagon/test_mpyi.S
 create mode 100644 tests/tcg/hexagon/test_overflow.S
 create mode 100644 tests/tcg/hexagon/test_packet.S
 create mode 100644 tests/tcg/hexagon/test_reorder.S
 create mode 100644 tests/tcg/hexagon/test_round.S
 create mode 100644 tests/tcg/hexagon/test_vavgw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpb.S
 create mode 100644 tests/tcg/hexagon/test_vcmpw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpy.S
 create mode 100644 tests/tcg/hexagon/test_vlsrw.S
 create mode 100644 tests/tcg/hexagon/test_vmaxh.S
 create mode 100644 tests/tcg/hexagon/test_vminh.S
 create mode 100644 tests/tcg/hexagon/test_vpmpyh.S
 create mode 100644 tests/tcg/hexagon/test_vspliceb.S

diff --git a/tests/tcg/hexagon/Makefile.target 
b/tests/tcg/hexagon/Makefile.target
index 616af697fe..b5323cba05 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -32,7 +32,7 @@ CFLAGS += -Wno-incompatible-pointer-types 
-Wno-undefined-internal
 HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon
 VPATH += $(HEX_SRC)
 
-first: $(HEX_SRC)/first.S
+%: $(HEX_SRC)/%.S $(HEX_SRC)/crt.S
$(CC) -static -mv67 -nostdlib $^ -o $@
 
 HEX_TESTS = first
@@ -43,4 +43,38 @@ HEX_TESTS += mem_noshuf
 HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_add
+HEX_TESTS += test_andp
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_call
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+HEX_TESTS += test_cmpy
+HEX_TESTS += test_djump
+HEX_TESTS += test_dotnew
+HEX_TESTS += test_dstore
+HEX_TESTS += test_ext
+HEX_TESTS += test_fibonacci
+HEX_TESTS += test_hello
+HEX_TESTS += test_hl
+HEX_TESTS += test_hwloops
+HEX_TESTS += test_jmp
+HEX_TESTS += test_lsr
+HEX_TESTS += test_mpyi
+HEX_TESTS += test_overflow
+HEX_TESTS += test_packet
+HEX_

[PATCH v4 06/12] target/hexagon: introduce new helper functions

2021-04-15 Thread Alessandro Di Federico via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 target/hexagon/genptr.c | 188 
 target/hexagon/genptr.h |  22 +
 target/hexagon/macros.h |   9 ++
 3 files changed, 219 insertions(+)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 1ddb4360f1..024419bf39 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -28,6 +28,12 @@
 #include "gen_tcg.h"
 #include "genptr.h"
 
+TCGv gen_read_reg(TCGv result, int num)
+{
+tcg_gen_mov_tl(result, hex_gpr[num]);
+return result;
+}
+
 TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
@@ -330,5 +336,187 @@ static inline void gen_store_conditional8(CPUHexagonState 
*env,
 tcg_gen_movi_tl(hex_llsc_addr, ~0);
 }
 
+void gen_store32(TCGv vaddr, TCGv src, tcg_target_long width, unsigned slot)
+{
+tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
+tcg_gen_movi_tl(hex_store_width[slot], width);
+tcg_gen_mov_tl(hex_store_val32[slot], src);
+}
+
+void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 1, slot);
+ctx->store_width[slot] = 1;
+}
+
+void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 2, slot);
+ctx->store_width[slot] = 2;
+}
+
+void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 4, slot);
+ctx->store_width[slot] = 4;
+}
+
+
+void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, DisasContext *ctx,
+unsigned slot)
+{
+tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
+tcg_gen_movi_tl(hex_store_width[slot], 8);
+tcg_gen_mov_i64(hex_store_val64[slot], src);
+ctx->store_width[slot] = 8;
+}
+
+void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_gpr[HEX_REG_USR], hex_gpr[HEX_REG_USR], val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+}
+
+void gen_set_usr_fieldi(int field, int x)
+{
+TCGv val = tcg_const_tl(x);
+gen_set_usr_field(field, val);
+tcg_temp_free(val);
+}
+
+void gen_write_new_pc(TCGv addr)
+{
+/* If there are multiple branches in a packet, ignore the second one */
+TCGv zero = tcg_const_tl(0);
+tcg_gen_movcond_tl(TCG_COND_NE, hex_next_PC, hex_branch_taken, zero,
+   hex_next_PC, addr);
+tcg_gen_movi_tl(hex_branch_taken, 1);
+tcg_temp_free(zero);
+}
+
+void gen_sat_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_const_i32((1 << (width - 1)) - 1);
+TCGv min_val = tcg_const_i32(-(1 << (width - 1)));
+tcg_gen_smin_tl(dest, source, max_val);
+tcg_gen_smax_tl(dest, dest, min_val);
+tcg_temp_free_i32(max_val);
+tcg_temp_free_i32(min_val);
+}
+
+void gen_sat_i32_ext(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_sat_i32(dest, source, width);
+TCGv zero = tcg_const_i32(0);
+TCGv one = tcg_const_i32(1);
+tcg_gen_movcond_i32(TCG_COND_NE, ovfl, source, dest, one, zero);
+tcg_temp_free_i32(zero);
+tcg_temp_free_i32(one);
+}
+
+void gen_satu_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_const_i32((1 << width) - 1);
+tcg_gen_movcond_i32(TCG_COND_GTU, dest, source, max_val, max_val, source);
+TCGv_i32 zero = tcg_const_i32(0);
+tcg_gen_movcond_i32(TCG_COND_LT, dest, source, zero, zero, dest);
+tcg_temp_free_i32(max_val);
+tcg_temp_free_i32(zero);
+}
+
+void gen_satu_i32_ext(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_satu_i32(dest, source, width);
+TCGv zero = tcg_const_i32(0);
+TCGv one = tcg_const_i32(1);
+tcg_gen_movcond_i32(TCG_COND_NE, ovfl, dest, source, one, zero);
+tcg_temp_free_i32(zero);
+tcg_temp_free_i32(one);
+}
+
+void gen_sat_i64(TCGv_i64 dest, TCGv_i64 source, int width)
+{
+TCGv_i64 max_val = tcg_const_i64((1 << (width - 1)) - 1);
+TCGv_i64 min_val = tcg_const_i64(-(1 << (width - 1)));
+tcg_gen_smin_i64(dest, source, max_val);
+tcg_gen_smax_i64(dest, dest, min_val);
+tcg_temp_free_i64(max_val);
+tcg_temp_free_i64(min_val);
+}
+
+void gen_sat_i64_ext(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int width)
+{
+gen_sat_i64(dest, source, width);
+TCGv_i64 ovfl_64 = tcg_temp_new_i64();
+TCGv_i64 zero = tcg_const_i64(0);
+TCGv_i64 one = tcg_const_i64(1);
+tcg_gen_movcond_i64(TCG_COND_NE, ovfl_64, dest, source, one, zero);
+tcg_gen_trunc_i64_tl(ovfl, ovfl_64);
+tcg_temp_free_i64(ovfl_64);
+tcg_temp_free_i64(zero);
+tcg_temp_free_i64(one);
+}
+
+void gen_satu_i64(TCGv_i64 dest, TCGv_i64 source, int width)
+{
+TCGv_i64 max_val = tcg_const_i64((1 << width) - 1);
+tcg_gen_movcond_i64(TCG_CON

[PATCH v4 08/12] target/hexagon: prepare input for the idef-parser

2021-04-15 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Introduce infrastructure necessary to produce a file suitable for being
parsed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_idef_parser_funcs.py | 114 ++
 target/hexagon/idef-parser/macros.inc   | 150 
 target/hexagon/idef-parser/prepare  |  24 
 target/hexagon/meson.build  |  17 +++
 4 files changed, 305 insertions(+)
 create mode 100644 target/hexagon/gen_idef_parser_funcs.py
 create mode 100644 target/hexagon/idef-parser/macros.inc
 create mode 100755 target/hexagon/idef-parser/prepare

diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
new file mode 100644
index 00..7b8e0f6981
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+##
+##  This program 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.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, see .
+##
+
+import sys
+import re
+import string
+from io import StringIO
+
+import hex_common
+
+##
+## Generate code to be fed to the idef_parser
+##
+## Consider A2_add:
+##
+## Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
+##
+## We produce:
+##
+## A2_add(RdV, in RsV, in RtV) {
+##   { RdV=RsV+RtV;}
+## }
+##
+## A2_add represents the instruction tag. Then we have a list of TCGv
+## that the code generated by the parser can expect in input. Some of
+## them are inputs ("in" prefix), while some others are outputs.
+##
+def main():
+hex_common.read_semantics_file(sys.argv[1])
+hex_common.read_attribs_file(sys.argv[2])
+hex_common.read_overrides_file(sys.argv[3])
+hex_common.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[4], 'w') as f:
+f.write('#include "macros.inc"\n\n')
+
+for tag in hex_common.tags:
+## Skip the priv instructions
+if ( "A_PRIV" in hex_common.attribdict[tag] ) :
+continue
+## Skip the guest instructions
+if ( "A_GUEST" in hex_common.attribdict[tag] ) :
+continue
+## Skip instructions using switch
+if ( tag in {'S4_vrcrotate_acc', 'S4_vrcrotate'} ) :
+continue
+## Skip trap instructions
+if ( tag in {'J2_trap0', 'J2_trap1'} ) :
+continue
+## Skip 128-bit instructions
+if ( tag in {'A7_croundd_ri', 'A7_croundd_rr'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag.startswith('S2_cabacdecbin') ) :
+continue
+if ( tag.startswith('Y') ) :
+continue
+if ( tag.startswith('V6_') ) :
+continue
+if ( tag.startswith('F') ) :
+continue
+if ( tag.endswith('_locked') ) :
+continue
+
+regs = tagregs[tag]
+imms = tagimms[tag]
+
+arguments = []
+if hex_common.need_ea(tag):
+arguments.append("EA")
+
+for regtype,regid,toss,numregs in regs:
+prefix = "in " if hex_common.is_read(regid) else ""
+
+is_pair = hex_common.is_pair(regid)
+is_single_old = (hex_common.is_single(regid)
+ and hex_common.is_old_val(regtype, regid, 
tag))
+is_single_new = (hex_common.is_single(regid)
+ and hex_common.is_new_val(regtype, regid, 
tag))
+
+if is_pair or is_single_old:
+arguments.append("%s%s%sV" % (prefix, regtype, regid))
+elif is_single_new:
+arguments.append("%s%s%sN" % (prefix, regtype, regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+for immlett,bits,immshift in imms:
+arguments.append(hex_common.imm_name(immlett))
+
+f.write("%s(%s) {\n" % (tag, ", ".join(arguments)))
+f.write("%s\n" % hex_common.semdict[tag])
+f.write("}\n\n")
+
+if __name__ == "__main__":
+main()
diff --git a/target/hexagon/idef-parser/macros.inc 
b/target/hexagon/idef-parser/macros.inc
new

[PATCH v4 05/12] target/hexagon: make helper functions non-static

2021-04-15 Thread Alessandro Di Federico via
From: Paolo Montesel 

Make certain helper functions non-static, making them available outside
genptr.c. These functions are required by code generated by the
idef-parser.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/genptr.c | 7 ---
 target/hexagon/genptr.h | 6 ++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index fd18aabe8d..1ddb4360f1 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -26,8 +26,9 @@
 #include "translate.h"
 #include "macros.h"
 #include "gen_tcg.h"
+#include "genptr.h"
 
-static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
+TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
 return pred;
@@ -54,7 +55,7 @@ static inline void gen_log_predicated_reg_write(int rnum, 
TCGv val,
 tcg_temp_free(slot_mask);
 }
 
-static inline void gen_log_reg_write(int rnum, TCGv val)
+void gen_log_reg_write(int rnum, TCGv val)
 {
 tcg_gen_mov_tl(hex_new_value[rnum], val);
 #if HEX_DEBUG
@@ -118,7 +119,7 @@ static void gen_log_reg_write_pair(int rnum, TCGv_i64 val)
 #endif
 }
 
-static inline void gen_log_pred_write(int pnum, TCGv val)
+void gen_log_pred_write(int pnum, TCGv val)
 {
 TCGv zero = tcg_const_tl(0);
 TCGv base_val = tcg_temp_new();
diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h
index c158005d2a..e1dcd24b0e 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -19,7 +19,13 @@
 #define HEXAGON_GENPTR_H
 
 #include "insn.h"
+#include "tcg/tcg.h"
+#include "translate.h"
 
 extern const SemanticInsn opcode_genptr[];
 
+TCGv gen_read_preg(TCGv pred, uint8_t num);
+void gen_log_reg_write(int rnum, TCGv val);
+void gen_log_pred_write(int pnum, TCGv val);
+
 #endif
-- 
2.31.1




[PATCH v4 00/12] target/hexagon: introduce idef-parser

2021-04-15 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This patchset introduces the idef-parser for target/hexagon.

It's the fourth iteration of the patchset and includes fixes suggested
in previous iterations.

`idef-parser` is a build-time tool built using flex and bison. Its aim
is to generate a large part of the tiny code generator frontend for
Hexagon. The prototype of idef-parser has been presented at KVM Forum
2019 ("QEMU-Hexagon: Automatic Translation of the ISA Manual Pseudcode
to Tiny Code Instructions"):

https://www.youtube.com/watch?v=3EpnTYBOXCI

`target/hexagon/idef-parser/README.rst` provides an overview of the
parser and its inner working.

A couple of notes:

* `idef-parser` also supports certain things that are not used in the
  most recently submitted version of the "Hexagon patch
  series". However, they will be needed and stripping them out of the
  parser is quite a bit of work.
* The build on the CI fails for the cross-i386-* jobs. This seems to be
  due to the fact that, despite we specified glib as a native
  dependency, meson still chooses the i386 bit version of the library,
  as opposed to the x86-64.
  Help on this matter is appreciated.
  The `clang-user` build fails too, but seems to be due reasons not
  concerning this patchset.
* Unlike the last iteration of this patchset, we no longer use local
  temps, which were detrimental for performance. Now, in order to
  handle side effects in ternary operators, the parser keeps track of
  nested ternary operators and their conditions. We then exploit that
  information to turn the side effect itself into a `movcond`. This is
  done by emitting a series of `and` instructions on the nested
  ternary operator conditions.

Alessandro Di Federico (5):
  tcg: expose TCGCond manipulation routines
  target/hexagon: update MAINTAINERS for idef-parser
  target/hexagon: import README for idef-parser
  target/hexagon: prepare input for the idef-parser
  target/hexagon: call idef-parser functions

Niccolò Izzo (2):
  target/hexagon: introduce new helper functions
  target/hexagon: import additional tests

Paolo Montesel (5):
  target/hexagon: make slot number an unsigned
  target/hexagon: make helper functions non-static
  target/hexagon: expose next PC in DisasContext
  target/hexagon: import lexer for idef-parser
  target/hexagon: import parser for idef-parser

 MAINTAINERS   |8 +
 include/tcg/tcg-cond.h|  101 +
 include/tcg/tcg.h |   70 +-
 target/hexagon/README |5 +
 target/hexagon/gen_idef_parser_funcs.py   |  114 +
 target/hexagon/gen_tcg_funcs.py   |   28 +-
 target/hexagon/genptr.c   |  201 +-
 target/hexagon/genptr.h   |   28 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  447 
 target/hexagon/idef-parser/idef-parser.h  |  254 ++
 target/hexagon/idef-parser/idef-parser.lex|  611 +
 target/hexagon/idef-parser/idef-parser.y  |  947 +++
 target/hexagon/idef-parser/macros.inc |  150 ++
 target/hexagon/idef-parser/parser-helpers.c   | 2374 +
 target/hexagon/idef-parser/parser-helpers.h   |  347 +++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/macros.h   |   11 +-
 target/hexagon/meson.build|   67 +-
 target/hexagon/translate.c|3 +-
 target/hexagon/translate.h|1 +
 tests/docker/dockerfiles/alpine.docker|2 +
 tests/docker/dockerfiles/centos7.docker   |2 +
 tests/docker/dockerfiles/centos8.docker   |2 +
 tests/docker/dockerfiles/debian10.docker  |3 +
 .../dockerfiles/fedora-i386-cross.docker  |3 +
 .../dockerfiles/fedora-win32-cross.docker |3 +
 .../dockerfiles/fedora-win64-cross.docker |3 +
 tests/docker/dockerfiles/fedora.docker|2 +
 tests/docker/dockerfiles/opensuse-leap.docker |2 +
 tests/docker/dockerfiles/ubuntu.docker|3 +
 tests/docker/dockerfiles/ubuntu1804.docker|3 +
 tests/docker/dockerfiles/ubuntu2004.docker|5 +-
 tests/tcg/hexagon/Makefile.target |   36 +-
 tests/tcg/hexagon/crt.S   |   28 +
 tests/tcg/hexagon/test_abs.S  |   20 +
 tests/tcg/hexagon/test_add.S  |   20 +
 tests/tcg/hexagon/test_andp.S |   23 +
 tests/tcg/hexagon/test_bitcnt.S   |   42 +
 tests/tcg/hexagon/test_bitsplit.S |   25 +
 tests/tcg/hexagon/test_call.S |   63 +
 tests/tcg/hexagon/test_clobber.S  |   35 +
 tests/tcg/hexagon/test_cmp.S  |   34 +
 tests/tcg/hexagon/test_cmpy.S |   31 +
 tests/tcg/hexagon/test_djump.S|   24 +
 tests/tcg/hexagon/test_dotnew.S   |   39 +
 tests/tcg/hexagon/test_dstore.S 

[PATCH v4 03/12] target/hexagon: import README for idef-parser

2021-04-15 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/README |   5 +
 target/hexagon/idef-parser/README.rst | 447 ++
 2 files changed, 452 insertions(+)
 create mode 100644 target/hexagon/idef-parser/README.rst

diff --git a/target/hexagon/README b/target/hexagon/README
index b0b2435070..2f2814380c 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -23,6 +23,10 @@ Hexagon-specific code are
 encode*.def Encoding patterns for each instruction
 iclass.def  Instruction class definitions used to determine
 legal VLIW slots for each instruction
+qemu/target/hexagon/idef-parser
+Parser that, given the high-level definitions of an instruction,
+produces a C function generating equivalent tiny code instructions.
+See README.rst.
 qemu/linux-user/hexagon
 Helpers for loading the ELF file and making Linux system calls,
 signals, etc
@@ -43,6 +47,7 @@ header files in /target/hexagon
 gen_tcg_funcs.py-> tcg_funcs_generated.c.inc
 gen_tcg_func_table.py   -> tcg_func_table_generated.c.inc
 gen_helper_funcs.py -> helper_funcs_generated.c.inc
+gen_idef_parser_funcs.py-> idef_parser_input.h
 
 Qemu helper functions have 3 parts
 DEF_HELPER declaration indicates the signature of the helper
diff --git a/target/hexagon/idef-parser/README.rst 
b/target/hexagon/idef-parser/README.rst
new file mode 100644
index 00..f4cb416e8b
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,447 @@
+Hexagon ISA instruction definitions to tinycode generator compiler
+--
+
+idef-parser is a small compiler able to translate the Hexagon ISA description
+language into tinycode generator code, that can be easily integrated into QEMU.
+
+Compilation Example
+---
+
+To better understand the scope of the idef-parser, we'll explore an applicative
+example. Let's start by one of the simplest Hexagon instruction: the ``add``.
+
+The ISA description language represents the ``add`` instruction as
+follows:
+
+.. code:: c
+
+   A2_add(RdV, in RsV, in RtV) {
+   { RdV=RsV+RtV;}
+   }
+
+idef-parser will compile the above code into the following code:
+
+.. code:: c
+
+   /* A2_add */
+   void emit_A2_add(DisasContext *ctx, Insn *insn, Packet *pkt, TCGv_i32 RdV,
+TCGv_i32 RsV, TCGv_i32 RtV)
+   /*  { RdV=RsV+RtV;} */
+   {
+   tcg_gen_movi_i32(RdV, 0);
+   TCGv_i32 tmp_0 = tcg_temp_new_i32();
+   tcg_gen_add_i32(tmp_0, RsV, RtV);
+   tcg_gen_mov_i32(RdV, tmp_0);
+   tcg_temp_free_i32(tmp_0);
+   }
+
+The output of the compilation process will be a function, containing the
+tinycode generator code, implementing the correct semantics. That function will
+not access any global variable, because all the accessed data structures will 
be
+passed explicitly as function parameters. Among the passed parameters we will
+have TCGv (tinycode variables) representing the input and output registers of
+the architecture, integers representing the immediates that come from the code,
+and other data structures which hold information about the disassemblation
+context (``DisasContext`` struct).
+
+Let's begin by describing the input code. The ``add`` instruction is associated
+with a unique identifier, in this case ``A2_add``, which allows to distinguish
+variants of the same instruction, and expresses the class to which the
+instruction belongs, in this case ``A2`` corresponds to the Hexagon
+``ALU32/ALU`` instruction subclass.
+
+After the instruction identifier, we have a series of parameters that 
represents
+TCG variables that will be passed to the generated function. Parameters marked
+with ``in`` are already initialized, while the others are output parameters.
+
+We will leverage this information to infer several information:
+
+-  Fill in the output function signature with the correct TCGv registers
+-  Fill in the output function signature with the immediate integers
+-  Keep track of which registers, among the declared one, have been
+   initialized
+
+Let's now observe the actual instruction description code, in this case:
+
+.. code:: c
+
+   { RdV=RsV+RtV;}
+
+This code is composed by a subset of the C syntax, and is the result of the
+application of some macro definitions contained in the ``macros.h`` file.
+
+This file is used to reduce the complexity of the input language where complex
+variants of similar constructs can be mapped to a unique primitive, so that the
+idef-parser has to handle a lower number of computation primitives.
+
+As you may notice, the description code modifies the registers which have been
+declared by the declaration statements. In this case all the three registers
+will be declared, ``RsV`` and ``RtV`` wil

[PATCH v3 10/12] target/hexagon: import parser for idef-parser

2021-03-30 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.y  |  940 +++
 target/hexagon/idef-parser/parser-helpers.c   | 2230 +
 target/hexagon/idef-parser/parser-helpers.h   |  344 +++
 target/hexagon/meson.build|   26 +-
 tests/docker/dockerfiles/alpine.docker|1 +
 tests/docker/dockerfiles/centos7.docker   |1 +
 tests/docker/dockerfiles/centos8.docker   |1 +
 tests/docker/dockerfiles/debian10.docker  |2 +
 .../dockerfiles/fedora-i386-cross.docker  |2 +
 .../dockerfiles/fedora-win32-cross.docker |2 +
 .../dockerfiles/fedora-win64-cross.docker |2 +
 tests/docker/dockerfiles/fedora.docker|1 +
 tests/docker/dockerfiles/opensuse-leap.docker |1 +
 tests/docker/dockerfiles/ubuntu.docker|2 +
 tests/docker/dockerfiles/ubuntu1804.docker|2 +
 tests/docker/dockerfiles/ubuntu2004.docker|4 +-
 16 files changed, 3559 insertions(+), 2 deletions(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.y
 create mode 100644 target/hexagon/idef-parser/parser-helpers.c
 create mode 100644 target/hexagon/idef-parser/parser-helpers.h

diff --git a/target/hexagon/idef-parser/idef-parser.y 
b/target/hexagon/idef-parser/idef-parser.y
new file mode 100644
index 00..5d96c9262a
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,940 @@
+%{
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "idef-parser.h"
+#include "parser-helpers.h"
+#include "idef-parser.tab.h"
+#include "idef-parser.yy.h"
+
+/* Uncomment this to disable yyasserts */
+/* #define NDEBUG */
+
+#define ERR_LINE_CONTEXT 40
+
+%}
+
+%lex-param {void *scanner}
+%parse-param {void *scanner}
+%parse-param {Context *c}
+
+%define parse.error verbose
+%define parse.lac full
+%define api.pure full
+
+%locations
+
+%union {
+GString *string;
+HexValue rvalue;
+HexSat sat;
+HexCast cast;
+HexExtract extract;
+HexMpy mpy;
+bool is_unsigned;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token INAME DREG DIMM DPRE DEA RREG WREG FREG FIMM RPRE WPRE FPRE FWRAP FEA 
VAR
+%token POW ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS 
ASL
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL ORL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE CONSTLL CONSTULL PC NPC LPCFG
+%token CANCEL IDENTITY PART1 BREV_4 BREV_8 ROTL INSBITS SETBITS EXTBITS 
EXTRANGE
+%token CAST4_8U SETOVF FAIL DEINTERLEAVE INTERLEAVE CARRY_FROM_ADD
+
+%token  REG IMM PRE
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement var
+%type  DREG DIMM DPRE RREG RPRE FAIL
+%type  if_stmt IF ':' '?'
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left '('
+%left ','
+%left '='
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left '?' ':'
+%left ORL
+%left ANDL
+%left '|'
+%left '^' ANDOR
+%left '&'
+%left EQ NEQ
+%left '<' '>' LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left '-' '+'
+%left POW
+%left '*' '/' '%' MPY
+%right '~' '!'
+%left '['
+%right CAST
+%right LOCNT BREV
+
+/* Bison Grammar */
+%%
+
+/* Input file containing the description of each hexagon instruction */
+input : instructions
+  {
+  YYACCEPT;
+  }
+  ;
+
+instructions : instruction instructions
+ | %empty
+ ;
+
+instruction : INAME
+  {
+  gen_inst(c, $1);
+  }
+  arguments
+  {
+  gen_inst_args(c, &@1);
+  }
+  code
+  {
+  gen_inst_code(c, &@1);
+  }
+| error /* Recover gracefully after instruction compilation error 
*/
+  {
+  free_instruction(c);
+  }
+;
+
+arguments : '(' ')'
+  | '(' argument_list ')';
+
+argument_list : decl ',' argument_list
+  | decl
+  ;
+
+var : VAR
+  {
+  track_string(c, $1.var.name);
+  $$ = $1;
+  }
+;
+
+/* Return the modified registers list */
+code : '{' statements '}'
+  

[PATCH v3 11/12] target/hexagon: call idef-parser functions

2021-03-30 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Extend gen_tcg_funcs.py in order to emit calls to the functions emitted
by the idef-parser, if available.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_tcg_funcs.py | 28 ++--
 target/hexagon/hex_common.py| 10 ++
 target/hexagon/meson.build  | 24 ++--
 3 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index db9f663a77..5980dab8ee 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -394,7 +394,29 @@ def gen_tcg_func(f, tag, regs, imms):
 if (hex_common.is_read(regid)):
 genptr_src_read_opn(f,regtype,regid,tag)
 
-if ( hex_common.skip_qemu_helper(tag) ):
+if hex_common.is_idef_parser_enabled(tag):
+declared = []
+## Handle registers
+for regtype,regid,toss,numregs in regs:
+if (hex_common.is_pair(regid)
+or (hex_common.is_single(regid)
+and hex_common.is_old_val(regtype, regid, tag))):
+declared.append("%s%sV" % (regtype, regid))
+if regtype == "M":
+declared.append("%s%sN" % (regtype, regid))
+elif hex_common.is_new_val(regtype, regid, tag):
+declared.append("%s%sN" % (regtype,regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+## Handle immediates
+for immlett,bits,immshift in imms:
+declared.append(hex_common.imm_name(immlett))
+
+arguments = ", ".join(["ctx", "insn", "pkt"] + declared)
+f.write("emit_%s(%s);\n" % (tag, arguments))
+
+elif ( hex_common.skip_qemu_helper(tag) ):
 f.write("fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
 else:
 ## Generate the call to the helper
@@ -455,12 +477,14 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.calculate_attribs()
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
 f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
+f.write("#include \"idef-generated-emitter.h.inc\"\n\n")
 
 for tag in hex_common.tags:
 ## Skip the priv instructions
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index b3b534057d..648ad29e94 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -28,6 +28,7 @@
 attribinfo = {}   # Register information and misc
 tags = [] # list of all tags
 overrides = {}# tags with helper overrides
+idef_parser_enabled = {} # tags enabled for idef-parser
 
 # We should do this as a hash for performance,
 # but to keep order let's keep it as a list.
@@ -201,6 +202,9 @@ def need_ea(tag):
 def skip_qemu_helper(tag):
 return tag in overrides.keys()
 
+def is_idef_parser_enabled(tag):
+return tag in idef_parser_enabled
+
 def imm_name(immlett):
 return "%siV" % immlett
 
@@ -232,3 +236,9 @@ def read_overrides_file(name):
 continue
 tag = overridere.findall(line)[0]
 overrides[tag] = True
+
+def read_idef_parser_enabled_file(name):
+global idef_parser_enabled
+with open(name, "r") as idef_parser_enabled_file:
+lines = idef_parser_enabled_file.read().strip().split("\n")
+idef_parser_enabled = set(lines)
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index 2b7d6c8c62..6adfe0468d 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -72,16 +72,6 @@ helper_protos_generated = custom_target(
 )
 hexagon_ss.add(helper_protos_generated)
 
-tcg_funcs_generated = custom_target(
-'tcg_funcs_generated.c.inc',
-output: 'tcg_funcs_generated.c.inc',
-input: 'gen_tcg_funcs.py',
-depends: [semantics_generated],
-depend_files: [hex_common_py, attribs_def, gen_tcg_h],
-command: [python, '@INPUT@', semantics_generated, attribs_def, gen_tcg_h, 
'@OUTPUT@'],
-)
-hexagon_ss.add(tcg_funcs_generated)
-
 tcg_func_table_generated = custom_target(
 'tcg_func_table_generated.c.inc',
 output: 'tcg_func_table_generated.c.inc',
@@ -234,4 +224,18 @@ idef_generated_tcg = custom_target(
 command: [idef_parser, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@', '@OUTPUT2@'],
 )
 
+idef_generated_list = idef_generated_tcg[2].full_path()
+
+hexagon_ss.add(idef_generated_tcg)
+
+tcg_funcs_generated = custom_target(
+'tcg_funcs_generated.c.inc',
+output: 'tcg_funcs_generated.c.inc',
+input: 'gen_tcg_funcs.py',
+depends: [semantics_generated, idef_generated_tcg],
+depend_files: [hex_common_py, attribs_def, gen_tcg_h],
+command: [pytho

[PATCH v3 06/12] target/hexagon: introduce new helper functions

2021-03-30 Thread Alessandro Di Federico via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 target/hexagon/genptr.c | 173 
 target/hexagon/genptr.h |  17 
 target/hexagon/macros.h |   9 +++
 3 files changed, 199 insertions(+)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 1ddb4360f1..adab1d395c 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -28,6 +28,12 @@
 #include "gen_tcg.h"
 #include "genptr.h"
 
+TCGv gen_read_reg(TCGv result, int num)
+{
+tcg_gen_mov_tl(result, hex_gpr[num]);
+return result;
+}
+
 TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
@@ -330,5 +336,172 @@ static inline void gen_store_conditional8(CPUHexagonState 
*env,
 tcg_gen_movi_tl(hex_llsc_addr, ~0);
 }
 
+void gen_store32(TCGv vaddr, TCGv src, tcg_target_long width, unsigned slot)
+{
+tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
+tcg_gen_movi_tl(hex_store_width[slot], width);
+tcg_gen_mov_tl(hex_store_val32[slot], src);
+}
+
+void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 1, slot);
+ctx->store_width[slot] = 1;
+}
+
+void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 2, slot);
+ctx->store_width[slot] = 2;
+}
+
+void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 4, slot);
+ctx->store_width[slot] = 4;
+}
+
+
+void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, DisasContext *ctx,
+unsigned slot)
+{
+tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
+tcg_gen_movi_tl(hex_store_width[slot], 8);
+tcg_gen_mov_i64(hex_store_val64[slot], src);
+ctx->store_width[slot] = 8;
+}
+
+void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_gpr[HEX_REG_USR], hex_gpr[HEX_REG_USR], val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+}
+
+void gen_set_usr_fieldi(int field, int x)
+{
+TCGv val = tcg_const_tl(x);
+gen_set_usr_field(field, val);
+tcg_temp_free(val);
+}
+
+void gen_write_new_pc(TCGv addr)
+{
+/* If there are multiple branches in a packet, ignore the second one */
+TCGv zero = tcg_const_tl(0);
+tcg_gen_movcond_tl(TCG_COND_NE, hex_next_PC, hex_branch_taken, zero,
+   hex_next_PC, addr);
+tcg_gen_movi_tl(hex_branch_taken, 1);
+tcg_temp_free(zero);
+}
+
+void gen_sat_i32(TCGv dest, TCGv source, int width, bool set_overflow)
+{
+TCGv max_val = tcg_const_i32((1 << (width - 1)) - 1);
+TCGv min_val = tcg_const_i32(-(1 << (width - 1)));
+tcg_gen_movcond_i32(TCG_COND_GT, dest, source, max_val, max_val, source);
+tcg_gen_movcond_i32(TCG_COND_LT, dest, source, min_val, min_val, dest);
+/* Set Overflow Bit */
+if (set_overflow) {
+TCGv ovf = tcg_temp_new();
+TCGv one = tcg_const_i32(1);
+GET_USR_FIELD(USR_OVF, ovf);
+tcg_gen_movcond_i32(TCG_COND_GT, ovf, source, max_val, one, ovf);
+tcg_gen_movcond_i32(TCG_COND_LT, ovf, source, min_val, one, ovf);
+SET_USR_FIELD(USR_OVF, ovf);
+tcg_temp_free_i32(ovf);
+tcg_temp_free_i32(one);
+}
+tcg_temp_free_i32(max_val);
+tcg_temp_free_i32(min_val);
+}
+
+void gen_satu_i32(TCGv dest, TCGv source, int width, bool set_overflow)
+{
+TCGv max_val = tcg_const_i32((1 << width) - 1);
+tcg_gen_movcond_i32(TCG_COND_GTU, dest, source, max_val, max_val, source);
+TCGv_i32 zero = tcg_const_i32(0);
+tcg_gen_movcond_i32(TCG_COND_LT, dest, source, zero, zero, dest);
+/* Set Overflow Bit */
+if (set_overflow) {
+TCGv ovf = tcg_temp_new();
+TCGv one = tcg_const_i32(1);
+GET_USR_FIELD(USR_OVF, ovf);
+tcg_gen_movcond_i32(TCG_COND_GTU, ovf, source, max_val, one, ovf);
+SET_USR_FIELD(USR_OVF, ovf);
+tcg_temp_free_i32(ovf);
+tcg_temp_free_i32(one);
+}
+tcg_temp_free_i32(max_val);
+tcg_temp_free_i32(zero);
+}
+
+void gen_sat_i64(TCGv_i64 dest, TCGv_i64 source, int width, bool set_overflow)
+{
+TCGv_i64 max_val = tcg_const_i64((1 << (width - 1)) - 1);
+TCGv_i64 min_val = tcg_const_i64(-(1 << (width - 1)));
+tcg_gen_movcond_i64(TCG_COND_GT, dest, source, max_val, max_val, source);
+tcg_gen_movcond_i64(TCG_COND_LT, dest, source, min_val, min_val, dest);
+/* Set Overflow Bit */
+if (set_overflow) {
+TCGv ovf = tcg_temp_new();
+TCGv_i64 ovf_ext = tcg_temp_new_i64();
+TCGv_i64 one = tcg_const_i64(1);
+GET_USR_FIELD(USR_OVF, ovf);
+tcg_gen_ext_i32_i64(ovf_ext, ovf);
+tcg_gen_movcond_i64(TCG_COND_GT,
+ovf

[PATCH v3 12/12] target/hexagon: import additional tests

2021-03-30 Thread Alessandro Di Federico via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 tests/tcg/hexagon/Makefile.target  | 35 -
 tests/tcg/hexagon/crt.S| 28 +
 tests/tcg/hexagon/test_abs.S   | 20 ++
 tests/tcg/hexagon/test_add.S   | 20 ++
 tests/tcg/hexagon/test_andp.S  | 23 +++
 tests/tcg/hexagon/test_bitcnt.S| 42 
 tests/tcg/hexagon/test_bitsplit.S  | 25 
 tests/tcg/hexagon/test_call.S  | 63 ++
 tests/tcg/hexagon/test_clobber.S   | 35 +
 tests/tcg/hexagon/test_cmp.S   | 34 
 tests/tcg/hexagon/test_cmpy.S  | 31 +++
 tests/tcg/hexagon/test_djump.S | 24 
 tests/tcg/hexagon/test_dotnew.S| 39 ++
 tests/tcg/hexagon/test_dstore.S| 29 ++
 tests/tcg/hexagon/test_ext.S   | 18 +
 tests/tcg/hexagon/test_fibonacci.S | 33 
 tests/tcg/hexagon/test_hello.S | 21 ++
 tests/tcg/hexagon/test_hl.S| 19 +
 tests/tcg/hexagon/test_hwloops.S   | 25 
 tests/tcg/hexagon/test_jmp.S   | 25 
 tests/tcg/hexagon/test_lsr.S   | 39 ++
 tests/tcg/hexagon/test_mpyi.S  | 20 ++
 tests/tcg/hexagon/test_packet.S| 26 
 tests/tcg/hexagon/test_reorder.S   | 31 +++
 tests/tcg/hexagon/test_round.S | 31 +++
 tests/tcg/hexagon/test_vavgw.S | 33 
 tests/tcg/hexagon/test_vcmpb.S | 32 +++
 tests/tcg/hexagon/test_vcmpw.S | 29 ++
 tests/tcg/hexagon/test_vcmpy.S | 50 
 tests/tcg/hexagon/test_vlsrw.S | 23 +++
 tests/tcg/hexagon/test_vmaxh.S | 37 ++
 tests/tcg/hexagon/test_vminh.S | 37 ++
 tests/tcg/hexagon/test_vpmpyh.S| 30 ++
 tests/tcg/hexagon/test_vspliceb.S  | 33 
 34 files changed, 1039 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/hexagon/crt.S
 create mode 100644 tests/tcg/hexagon/test_abs.S
 create mode 100644 tests/tcg/hexagon/test_add.S
 create mode 100644 tests/tcg/hexagon/test_andp.S
 create mode 100644 tests/tcg/hexagon/test_bitcnt.S
 create mode 100644 tests/tcg/hexagon/test_bitsplit.S
 create mode 100644 tests/tcg/hexagon/test_call.S
 create mode 100644 tests/tcg/hexagon/test_clobber.S
 create mode 100644 tests/tcg/hexagon/test_cmp.S
 create mode 100644 tests/tcg/hexagon/test_cmpy.S
 create mode 100644 tests/tcg/hexagon/test_djump.S
 create mode 100644 tests/tcg/hexagon/test_dotnew.S
 create mode 100644 tests/tcg/hexagon/test_dstore.S
 create mode 100644 tests/tcg/hexagon/test_ext.S
 create mode 100644 tests/tcg/hexagon/test_fibonacci.S
 create mode 100644 tests/tcg/hexagon/test_hello.S
 create mode 100644 tests/tcg/hexagon/test_hl.S
 create mode 100644 tests/tcg/hexagon/test_hwloops.S
 create mode 100644 tests/tcg/hexagon/test_jmp.S
 create mode 100644 tests/tcg/hexagon/test_lsr.S
 create mode 100644 tests/tcg/hexagon/test_mpyi.S
 create mode 100644 tests/tcg/hexagon/test_packet.S
 create mode 100644 tests/tcg/hexagon/test_reorder.S
 create mode 100644 tests/tcg/hexagon/test_round.S
 create mode 100644 tests/tcg/hexagon/test_vavgw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpb.S
 create mode 100644 tests/tcg/hexagon/test_vcmpw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpy.S
 create mode 100644 tests/tcg/hexagon/test_vlsrw.S
 create mode 100644 tests/tcg/hexagon/test_vmaxh.S
 create mode 100644 tests/tcg/hexagon/test_vminh.S
 create mode 100644 tests/tcg/hexagon/test_vpmpyh.S
 create mode 100644 tests/tcg/hexagon/test_vspliceb.S

diff --git a/tests/tcg/hexagon/Makefile.target 
b/tests/tcg/hexagon/Makefile.target
index 616af697fe..f4a774cda1 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -32,7 +32,7 @@ CFLAGS += -Wno-incompatible-pointer-types 
-Wno-undefined-internal
 HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon
 VPATH += $(HEX_SRC)
 
-first: $(HEX_SRC)/first.S
+%: $(HEX_SRC)/%.S $(HEX_SRC)/crt.S
$(CC) -static -mv67 -nostdlib $^ -o $@
 
 HEX_TESTS = first
@@ -43,4 +43,37 @@ HEX_TESTS += mem_noshuf
 HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_add
+HEX_TESTS += test_andp
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_call
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+HEX_TESTS += test_cmpy
+HEX_TESTS += test_djump
+HEX_TESTS += test_dotnew
+HEX_TESTS += test_dstore
+HEX_TESTS += test_ext
+HEX_TESTS += test_fibonacci
+HEX_TESTS += test_hello
+HEX_TESTS += test_hl
+HEX_TESTS += test_hwloops
+HEX_TESTS += test_jmp
+HEX_TESTS += test_lsr
+HEX_TESTS += test_mpyi
+HEX_TESTS += test_packet
+HEX_TESTS += test_reorder
+HEX_TESTS += test_round
+HEX_TESTS += test_vavgw
+HEX_TESTS += test_vcmpb
+HEX_TESTS += test_vcmpw
+HEX_TESTS += test_vcmpy
+HEX_TE

[PATCH v3 08/12] target/hexagon: prepare input for the idef-parser

2021-03-30 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Introduce infrastructure necessary to produce a file suitable for being
parsed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_idef_parser_funcs.py | 114 ++
 target/hexagon/idef-parser/macros.inc   | 150 
 target/hexagon/idef-parser/prepare  |  24 
 target/hexagon/meson.build  |  18 +++
 4 files changed, 306 insertions(+)
 create mode 100644 target/hexagon/gen_idef_parser_funcs.py
 create mode 100644 target/hexagon/idef-parser/macros.inc
 create mode 100755 target/hexagon/idef-parser/prepare

diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
new file mode 100644
index 00..7b8e0f6981
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+##
+##  This program 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.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, see .
+##
+
+import sys
+import re
+import string
+from io import StringIO
+
+import hex_common
+
+##
+## Generate code to be fed to the idef_parser
+##
+## Consider A2_add:
+##
+## Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
+##
+## We produce:
+##
+## A2_add(RdV, in RsV, in RtV) {
+##   { RdV=RsV+RtV;}
+## }
+##
+## A2_add represents the instruction tag. Then we have a list of TCGv
+## that the code generated by the parser can expect in input. Some of
+## them are inputs ("in" prefix), while some others are outputs.
+##
+def main():
+hex_common.read_semantics_file(sys.argv[1])
+hex_common.read_attribs_file(sys.argv[2])
+hex_common.read_overrides_file(sys.argv[3])
+hex_common.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[4], 'w') as f:
+f.write('#include "macros.inc"\n\n')
+
+for tag in hex_common.tags:
+## Skip the priv instructions
+if ( "A_PRIV" in hex_common.attribdict[tag] ) :
+continue
+## Skip the guest instructions
+if ( "A_GUEST" in hex_common.attribdict[tag] ) :
+continue
+## Skip instructions using switch
+if ( tag in {'S4_vrcrotate_acc', 'S4_vrcrotate'} ) :
+continue
+## Skip trap instructions
+if ( tag in {'J2_trap0', 'J2_trap1'} ) :
+continue
+## Skip 128-bit instructions
+if ( tag in {'A7_croundd_ri', 'A7_croundd_rr'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag.startswith('S2_cabacdecbin') ) :
+continue
+if ( tag.startswith('Y') ) :
+continue
+if ( tag.startswith('V6_') ) :
+continue
+if ( tag.startswith('F') ) :
+continue
+if ( tag.endswith('_locked') ) :
+continue
+
+regs = tagregs[tag]
+imms = tagimms[tag]
+
+arguments = []
+if hex_common.need_ea(tag):
+arguments.append("EA")
+
+for regtype,regid,toss,numregs in regs:
+prefix = "in " if hex_common.is_read(regid) else ""
+
+is_pair = hex_common.is_pair(regid)
+is_single_old = (hex_common.is_single(regid)
+ and hex_common.is_old_val(regtype, regid, 
tag))
+is_single_new = (hex_common.is_single(regid)
+ and hex_common.is_new_val(regtype, regid, 
tag))
+
+if is_pair or is_single_old:
+arguments.append("%s%s%sV" % (prefix, regtype, regid))
+elif is_single_new:
+arguments.append("%s%s%sN" % (prefix, regtype, regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+for immlett,bits,immshift in imms:
+arguments.append(hex_common.imm_name(immlett))
+
+f.write("%s(%s) {\n" % (tag, ", ".join(arguments)))
+f.write("%s\n" % hex_common.semdict[tag])
+f.write("}\n\n")
+
+if __name__ == "__main__":
+main()
diff --git a/target/hexagon/idef-parser/macros.inc 
b/target/hexagon/idef-parser/macros.inc
new

[PATCH v3 02/12] target/hexagon: update MAINTAINERS for idef-parser

2021-03-30 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 554be84b32..13de7ecc36 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -194,11 +194,19 @@ Hexagon TCG CPUs
 M: Taylor Simpson 
 S: Supported
 F: target/hexagon/
+X: target/hexagon/idef-parser/
+X: target/hexagon/gen_idef_parser_funcs.py
 F: linux-user/hexagon/
 F: tests/tcg/hexagon/
 F: disas/hexagon.c
 F: default-configs/targets/hexagon-linux-user.mak
 
+Hexagon idef-parser
+M: Alessandro Di Federico 
+S: Supported
+F: target/hexagon/idef-parser/
+F: target/hexagon/gen_idef_parser_funcs.py
+
 HPPA (PA-RISC) TCG CPUs
 M: Richard Henderson 
 S: Maintained
-- 
2.31.1




[PATCH v3 00/12] target/hexagon: introduce idef-parser

2021-03-30 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This patchset introduces the idef-parser for target/hexagon.

It's the third iteration of the patchset and includes fixes suggested
in the previous iteration.

`idef-parser` is a build-time tool built using flex and bison. Its aim
is to generate a large part of the tiny code generator frontend for
Hexagon. The prototype of idef-parser has been presented at KVM Forum
2019 ("QEMU-Hexagon: Automatic Translation of the ISA Manual Pseudcode
to Tiny Code Instructions"):

https://www.youtube.com/watch?v=3EpnTYBOXCI

`target/hexagon/idef-parser/README.rst` provides an overview of the
parser and its inner working.

A couple of notes:

* `idef-parser` also supports certain things that are not used in the
  most recently submitted version of the "Hexagon patch
  series". However, they will be needed and stripping them out of the
  parser is quite a bit of work.
* checkpatch.pl complains on a single macro which has a trailing
  semi-colon, which is required.
* The build on the CI fails for the cross-i386-* jobs. This seems to be
  due to the fact that, despite we specified glib as a native
  dependency, meson still chooses the i386 bit version of the library,
  as opposed to the x86-64.
* This implementation no longer employs a conditional move to implement
  the ternary operator of the input language. We now employ proper
  control flow instructions (brcond). This is due to the fact that
  certain ternary expression have side effects. As a side effect, we had
  to switch from temporaries to local temporaries.

Alessandro Di Federico (5):
  tcg: expose TCGCond manipulation routines
  target/hexagon: update MAINTAINERS for idef-parser
  target/hexagon: import README for idef-parser
  target/hexagon: prepare input for the idef-parser
  target/hexagon: call idef-parser functions

Niccolò Izzo (2):
  target/hexagon: introduce new helper functions
  target/hexagon: import additional tests

Paolo Montesel (5):
  target/hexagon: make slot number an unsigned
  target/hexagon: make helper functions non-static
  target/hexagon: expose next PC in DisasContext
  target/hexagon: import lexer for idef-parser
  target/hexagon: import parser for idef-parser

 MAINTAINERS   |8 +
 include/tcg/tcg-cond.h|  101 +
 include/tcg/tcg.h |   70 +-
 target/hexagon/README |5 +
 target/hexagon/gen_idef_parser_funcs.py   |  114 +
 target/hexagon/gen_tcg_funcs.py   |   28 +-
 target/hexagon/genptr.c   |  186 +-
 target/hexagon/genptr.h   |   23 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  447 
 target/hexagon/idef-parser/idef-parser.h  |  240 ++
 target/hexagon/idef-parser/idef-parser.lex|  611 +
 target/hexagon/idef-parser/idef-parser.y  |  940 +++
 target/hexagon/idef-parser/macros.inc |  150 ++
 target/hexagon/idef-parser/parser-helpers.c   | 2230 +
 target/hexagon/idef-parser/parser-helpers.h   |  344 +++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/macros.h   |   11 +-
 target/hexagon/meson.build|   70 +-
 target/hexagon/translate.c|3 +-
 target/hexagon/translate.h|1 +
 tests/docker/dockerfiles/alpine.docker|2 +
 tests/docker/dockerfiles/centos7.docker   |2 +
 tests/docker/dockerfiles/centos8.docker   |2 +
 tests/docker/dockerfiles/debian10.docker  |3 +
 .../dockerfiles/fedora-i386-cross.docker  |3 +
 .../dockerfiles/fedora-win32-cross.docker |3 +
 .../dockerfiles/fedora-win64-cross.docker |3 +
 tests/docker/dockerfiles/fedora.docker|2 +
 tests/docker/dockerfiles/opensuse-leap.docker |2 +
 tests/docker/dockerfiles/ubuntu.docker|3 +
 tests/docker/dockerfiles/ubuntu1804.docker|3 +
 tests/docker/dockerfiles/ubuntu2004.docker|5 +-
 tests/tcg/hexagon/Makefile.target |   35 +-
 tests/tcg/hexagon/crt.S   |   28 +
 tests/tcg/hexagon/test_abs.S  |   20 +
 tests/tcg/hexagon/test_add.S  |   20 +
 tests/tcg/hexagon/test_andp.S |   23 +
 tests/tcg/hexagon/test_bitcnt.S   |   42 +
 tests/tcg/hexagon/test_bitsplit.S |   25 +
 tests/tcg/hexagon/test_call.S |   63 +
 tests/tcg/hexagon/test_clobber.S  |   35 +
 tests/tcg/hexagon/test_cmp.S  |   34 +
 tests/tcg/hexagon/test_cmpy.S |   31 +
 tests/tcg/hexagon/test_djump.S|   24 +
 tests/tcg/hexagon/test_dotnew.S   |   39 +
 tests/tcg/hexagon/test_dstore.S   |   29 +
 tests/tcg/hexagon/test_ext.S  |   18 +
 tests/tcg/hexagon/test_fibonacci.S|   33 +
 tests/tcg

[PATCH v3 04/12] target/hexagon: make slot number an unsigned

2021-03-30 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/genptr.c | 6 --
 target/hexagon/macros.h | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 7481f4c1dd..fd18aabe8d 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -33,7 +33,8 @@ static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
 return pred;
 }
 
-static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot)
+static inline void gen_log_predicated_reg_write(int rnum, TCGv val,
+unsigned slot)
 {
 TCGv one = tcg_const_tl(1);
 TCGv zero = tcg_const_tl(0);
@@ -62,7 +63,8 @@ static inline void gen_log_reg_write(int rnum, TCGv val)
 #endif
 }
 
-static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int slot)
+static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val,
+  unsigned slot)
 {
 TCGv val32 = tcg_temp_new();
 TCGv one = tcg_const_tl(1);
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index cfcb8173ba..d9473c8823 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -154,7 +154,7 @@
 #define LOAD_CANCEL(EA) do { CANCEL; } while (0)
 
 #ifdef QEMU_GENERATE
-static inline void gen_pred_cancel(TCGv pred, int slot_num)
+static inline void gen_pred_cancel(TCGv pred, unsigned slot_num)
  {
 TCGv slot_mask = tcg_const_tl(1 << slot_num);
 TCGv tmp = tcg_temp_new();
-- 
2.31.1




[PATCH v3 09/12] target/hexagon: import lexer for idef-parser

2021-03-30 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.h  | 240 +++
 target/hexagon/idef-parser/idef-parser.lex| 611 ++
 target/hexagon/meson.build|   4 +
 tests/docker/dockerfiles/alpine.docker|   1 +
 tests/docker/dockerfiles/centos7.docker   |   1 +
 tests/docker/dockerfiles/centos8.docker   |   1 +
 tests/docker/dockerfiles/debian10.docker  |   1 +
 .../dockerfiles/fedora-i386-cross.docker  |   1 +
 .../dockerfiles/fedora-win32-cross.docker |   1 +
 .../dockerfiles/fedora-win64-cross.docker |   1 +
 tests/docker/dockerfiles/fedora.docker|   1 +
 tests/docker/dockerfiles/opensuse-leap.docker |   1 +
 tests/docker/dockerfiles/ubuntu.docker|   1 +
 tests/docker/dockerfiles/ubuntu1804.docker|   1 +
 tests/docker/dockerfiles/ubuntu2004.docker|   3 +-
 15 files changed, 868 insertions(+), 1 deletion(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.h
 create mode 100644 target/hexagon/idef-parser/idef-parser.lex

diff --git a/target/hexagon/idef-parser/idef-parser.h 
b/target/hexagon/idef-parser/idef-parser.h
new file mode 100644
index 00..ecfa0174e2
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright(c) 2019-2021 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef IDEF_PARSER_H
+#define IDEF_PARSER_H
+
+#include 
+#include 
+#include 
+#include 
+
+#define TCGV_NAME_SIZE 7
+#define MAX_WRITTEN_REGS 32
+#define OFFSET_STR_LEN 32
+#define ALLOC_LIST_LEN 32
+#define ALLOC_NAME_SIZE 32
+#define INIT_LIST_LEN 32
+#define OUT_BUF_LEN (1024 * 1024)
+#define SIGNATURE_BUF_LEN (128 * 1024)
+#define HEADER_BUF_LEN (128 * 1024)
+
+/* Variadic macros to wrap the buffer printing functions */
+#define EMIT(c, ...) \
+do { \
+g_string_append_printf((c)->out_str, __VA_ARGS__);   \
+} while (0)
+
+#define EMIT_SIG(c, ...)   
\
+do {   
\
+g_string_append_printf((c)->signature_str, __VA_ARGS__);   
\
+} while (0)
+
+#define EMIT_HEAD(c, ...)  
\
+do {   
\
+g_string_append_printf((c)->header_str, __VA_ARGS__);  
\
+} while (0)
+
+/**
+ * Type of register, assigned to the HexReg.type field
+ */
+typedef enum {GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW} RegType;
+
+/**
+ * Types of control registers, assigned to the HexReg.id field
+ */
+typedef enum {SP, FP, LR, GP, LC0, LC1, SA0, SA1} CregType;
+
+/**
+ * Identifier string of the control registers, indexed by the CregType enum
+ */
+extern const char *creg_str[];
+
+/**
+ * Semantic record of the REG tokens, identifying registers
+ */
+typedef struct HexReg {
+CregType id;/**< Identifier of the register  */
+RegType type;   /**< Type of the register*/
+unsigned bit_width; /**< Bit width of the reg, 32 or 64 bits */
+} HexReg;
+
+/**
+ * Data structure, identifying a TCGv temporary value
+ */
+typedef struct HexTmp {
+int index;  /**< Index of the TCGv temporary value*/
+} HexTmp;
+
+/**
+ * Enum of the possible immediated, an immediate is a value which is known
+ * at tinycode generation time, e.g. an integer value, not a TCGv
+ */
+enum ImmUnionTag {I, VARIABLE, VALUE, QEMU_TMP, IMM_PC, IMM_CONSTEXT};
+
+/**
+ * Semantic record of the IMM token, identifying an immediate constant
+ */
+typedef struct HexImm {
+union {
+char id;/**< Identifier of the immediate */
+uint64_t value; /**< Immediate value (for VALUE type immediates) */
+uint64_t index; /**< Index of the immediate (for int temp vars)  */
+};
+enum ImmUnionTag type;  /**< Type of the immediate  */
+} HexImm;
+
+/**
+ * Semantic record of the PRE token, identifying a predicate
+ */
+typedef stru

[PATCH v3 07/12] target/hexagon: expose next PC in DisasContext

2021-03-30 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/translate.c | 3 ++-
 target/hexagon/translate.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index eeaad5f8ba..30ff3c5d51 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -503,11 +503,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, &pkt, false) > 0) {
 HEX_DEBUG_PRINT_PKT(&pkt);
 gen_start_packet(ctx, &pkt);
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, &pkt.insn[i], &pkt);
 }
 gen_commit_packet(ctx, &pkt);
-ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
+ctx->base.pc_next = ctx->npc;
 } else {
 gen_exception(HEX_EXCP_INVALID_PACKET);
 ctx->base.is_jmp = DISAS_NORETURN;
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 938f7fbb9f..2195e20f4b 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -36,6 +36,7 @@ typedef struct DisasContext {
 int preg_log_idx;
 uint8_t store_width[STORES_MAX];
 uint8_t s1_store_processed;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.31.1




[PATCH v3 03/12] target/hexagon: import README for idef-parser

2021-03-30 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/README |   5 +
 target/hexagon/idef-parser/README.rst | 447 ++
 2 files changed, 452 insertions(+)
 create mode 100644 target/hexagon/idef-parser/README.rst

diff --git a/target/hexagon/README b/target/hexagon/README
index b0b2435070..2f2814380c 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -23,6 +23,10 @@ Hexagon-specific code are
 encode*.def Encoding patterns for each instruction
 iclass.def  Instruction class definitions used to determine
 legal VLIW slots for each instruction
+qemu/target/hexagon/idef-parser
+Parser that, given the high-level definitions of an instruction,
+produces a C function generating equivalent tiny code instructions.
+See README.rst.
 qemu/linux-user/hexagon
 Helpers for loading the ELF file and making Linux system calls,
 signals, etc
@@ -43,6 +47,7 @@ header files in /target/hexagon
 gen_tcg_funcs.py-> tcg_funcs_generated.c.inc
 gen_tcg_func_table.py   -> tcg_func_table_generated.c.inc
 gen_helper_funcs.py -> helper_funcs_generated.c.inc
+gen_idef_parser_funcs.py-> idef_parser_input.h
 
 Qemu helper functions have 3 parts
 DEF_HELPER declaration indicates the signature of the helper
diff --git a/target/hexagon/idef-parser/README.rst 
b/target/hexagon/idef-parser/README.rst
new file mode 100644
index 00..f4cb416e8b
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,447 @@
+Hexagon ISA instruction definitions to tinycode generator compiler
+--
+
+idef-parser is a small compiler able to translate the Hexagon ISA description
+language into tinycode generator code, that can be easily integrated into QEMU.
+
+Compilation Example
+---
+
+To better understand the scope of the idef-parser, we'll explore an applicative
+example. Let's start by one of the simplest Hexagon instruction: the ``add``.
+
+The ISA description language represents the ``add`` instruction as
+follows:
+
+.. code:: c
+
+   A2_add(RdV, in RsV, in RtV) {
+   { RdV=RsV+RtV;}
+   }
+
+idef-parser will compile the above code into the following code:
+
+.. code:: c
+
+   /* A2_add */
+   void emit_A2_add(DisasContext *ctx, Insn *insn, Packet *pkt, TCGv_i32 RdV,
+TCGv_i32 RsV, TCGv_i32 RtV)
+   /*  { RdV=RsV+RtV;} */
+   {
+   tcg_gen_movi_i32(RdV, 0);
+   TCGv_i32 tmp_0 = tcg_temp_new_i32();
+   tcg_gen_add_i32(tmp_0, RsV, RtV);
+   tcg_gen_mov_i32(RdV, tmp_0);
+   tcg_temp_free_i32(tmp_0);
+   }
+
+The output of the compilation process will be a function, containing the
+tinycode generator code, implementing the correct semantics. That function will
+not access any global variable, because all the accessed data structures will 
be
+passed explicitly as function parameters. Among the passed parameters we will
+have TCGv (tinycode variables) representing the input and output registers of
+the architecture, integers representing the immediates that come from the code,
+and other data structures which hold information about the disassemblation
+context (``DisasContext`` struct).
+
+Let's begin by describing the input code. The ``add`` instruction is associated
+with a unique identifier, in this case ``A2_add``, which allows to distinguish
+variants of the same instruction, and expresses the class to which the
+instruction belongs, in this case ``A2`` corresponds to the Hexagon
+``ALU32/ALU`` instruction subclass.
+
+After the instruction identifier, we have a series of parameters that 
represents
+TCG variables that will be passed to the generated function. Parameters marked
+with ``in`` are already initialized, while the others are output parameters.
+
+We will leverage this information to infer several information:
+
+-  Fill in the output function signature with the correct TCGv registers
+-  Fill in the output function signature with the immediate integers
+-  Keep track of which registers, among the declared one, have been
+   initialized
+
+Let's now observe the actual instruction description code, in this case:
+
+.. code:: c
+
+   { RdV=RsV+RtV;}
+
+This code is composed by a subset of the C syntax, and is the result of the
+application of some macro definitions contained in the ``macros.h`` file.
+
+This file is used to reduce the complexity of the input language where complex
+variants of similar constructs can be mapped to a unique primitive, so that the
+idef-parser has to handle a lower number of computation primitives.
+
+As you may notice, the description code modifies the registers which have been
+declared by the declaration statements. In this case all the three registers
+will be declared, ``RsV`` and ``RtV`` wil

[PATCH v3 01/12] tcg: expose TCGCond manipulation routines

2021-03-30 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This commit moves into a separate file routines used to manipulate
TCGCond. These will be employed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 include/tcg/tcg-cond.h | 101 +
 include/tcg/tcg.h  |  70 +---
 2 files changed, 102 insertions(+), 69 deletions(-)
 create mode 100644 include/tcg/tcg-cond.h

diff --git a/include/tcg/tcg-cond.h b/include/tcg/tcg-cond.h
new file mode 100644
index 00..2a38a386d4
--- /dev/null
+++ b/include/tcg/tcg-cond.h
@@ -0,0 +1,101 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef TCG_COND_H
+#define TCG_COND_H
+
+/*
+ * Conditions.  Note that these are laid out for easy manipulation by
+ * the functions below:
+ *bit 0 is used for inverting;
+ *bit 1 is signed,
+ *bit 2 is unsigned,
+ *bit 3 is used with bit 0 for swapping signed/unsigned.
+ */
+typedef enum {
+/* non-signed */
+TCG_COND_NEVER  = 0 | 0 | 0 | 0,
+TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
+TCG_COND_EQ = 8 | 0 | 0 | 0,
+TCG_COND_NE = 8 | 0 | 0 | 1,
+/* signed */
+TCG_COND_LT = 0 | 0 | 2 | 0,
+TCG_COND_GE = 0 | 0 | 2 | 1,
+TCG_COND_LE = 8 | 0 | 2 | 0,
+TCG_COND_GT = 8 | 0 | 2 | 1,
+/* unsigned */
+TCG_COND_LTU= 0 | 4 | 0 | 0,
+TCG_COND_GEU= 0 | 4 | 0 | 1,
+TCG_COND_LEU= 8 | 4 | 0 | 0,
+TCG_COND_GTU= 8 | 4 | 0 | 1,
+} TCGCond;
+
+/* Invert the sense of the comparison.  */
+static inline TCGCond tcg_invert_cond(TCGCond c)
+{
+return (TCGCond)(c ^ 1);
+}
+
+/* Swap the operands in a comparison.  */
+static inline TCGCond tcg_swap_cond(TCGCond c)
+{
+return c & 6 ? (TCGCond)(c ^ 9) : c;
+}
+
+/* Create an "unsigned" version of a "signed" comparison.  */
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
+{
+return c & 2 ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Create a "signed" version of an "unsigned" comparison.  */
+static inline TCGCond tcg_signed_cond(TCGCond c)
+{
+return c & 4 ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Must a comparison be considered unsigned?  */
+static inline bool is_unsigned_cond(TCGCond c)
+{
+return (c & 4) != 0;
+}
+
+/*
+ * Create a "high" version of a double-word comparison.
+ * This removes equality from a LTE or GTE comparison.
+ */
+static inline TCGCond tcg_high_cond(TCGCond c)
+{
+switch (c) {
+case TCG_COND_GE:
+case TCG_COND_LE:
+case TCG_COND_GEU:
+case TCG_COND_LEU:
+return (TCGCond)(c ^ 8);
+default:
+return c;
+}
+}
+
+#endif /* TCG_COND_H */
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 0f0695e90d..3dc468ebd8 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -34,6 +34,7 @@
 #include "tcg/tcg-mo.h"
 #include "tcg-target.h"
 #include "qemu/int128.h"
+#include "tcg/tcg-cond.h"
 
 /* XXX: make safe guess about sizes */
 #define MAX_OP_PER_INSTR 266
@@ -407,75 +408,6 @@ typedef TCGv_ptr TCGv_env;
 /* Used to align parameters.  See the comment before tcgv_i32_temp.  */
 #define TCG_CALL_DUMMY_ARG  ((TCGArg)0)
 
-/* Conditions.  Note that these are laid out for easy manipulation by
-   the functions below:
- bit 0 is used for inverting;
- bit 1 is signed,
- bit 2 is unsigned,
- bit 3 is used with bit 0 for swapping signed/unsigned.  */
-typedef enum {
-/* non-signed */
-TCG_COND_NEVER  = 0 | 0 | 0 | 0,
-TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
-TCG_COND_EQ = 8 | 0 | 0 | 0,
-TCG_COND_NE = 8 | 0 | 0 | 1,
-/* signed */
-TCG_COND_LT = 0 | 0 | 2 | 0,
-TCG_COND_GE = 0 | 0 | 2 | 1,
-TCG_COND_LE = 8 | 0 | 2 | 0,
-TCG_COND_GT = 8 | 0 | 2 | 1,
-/* unsigned */
-TCG_COND_LTU= 0 | 4 | 0 | 0,
-TCG_COND_GEU= 0 | 4 | 0 | 1,
-TCG_COND_LEU= 8 | 4 | 0 

[PATCH v3 05/12] target/hexagon: make helper functions non-static

2021-03-30 Thread Alessandro Di Federico via
From: Paolo Montesel 

Make certain helper functions non-static, making them available outside
genptr.c. These functions are required by code generated by the
idef-parser.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/genptr.c | 7 ---
 target/hexagon/genptr.h | 6 ++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index fd18aabe8d..1ddb4360f1 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -26,8 +26,9 @@
 #include "translate.h"
 #include "macros.h"
 #include "gen_tcg.h"
+#include "genptr.h"
 
-static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
+TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
 return pred;
@@ -54,7 +55,7 @@ static inline void gen_log_predicated_reg_write(int rnum, 
TCGv val,
 tcg_temp_free(slot_mask);
 }
 
-static inline void gen_log_reg_write(int rnum, TCGv val)
+void gen_log_reg_write(int rnum, TCGv val)
 {
 tcg_gen_mov_tl(hex_new_value[rnum], val);
 #if HEX_DEBUG
@@ -118,7 +119,7 @@ static void gen_log_reg_write_pair(int rnum, TCGv_i64 val)
 #endif
 }
 
-static inline void gen_log_pred_write(int pnum, TCGv val)
+void gen_log_pred_write(int pnum, TCGv val)
 {
 TCGv zero = tcg_const_tl(0);
 TCGv base_val = tcg_temp_new();
diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h
index c158005d2a..e1dcd24b0e 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -19,7 +19,13 @@
 #define HEXAGON_GENPTR_H
 
 #include "insn.h"
+#include "tcg/tcg.h"
+#include "translate.h"
 
 extern const SemanticInsn opcode_genptr[];
 
+TCGv gen_read_preg(TCGv pred, uint8_t num);
+void gen_log_reg_write(int rnum, TCGv val);
+void gen_log_pred_write(int pnum, TCGv val);
+
 #endif
-- 
2.31.1




Re: [PATCH v2 02/10] target/hexagon: import README for idef-parser

2021-03-18 Thread Alessandro Di Federico via
On Wed, 10 Mar 2021 15:48:14 +
Taylor Simpson  wrote:

> Which instructions require this?  There must be an attribute that we
> could check to see if it is needed before emitting the TCG.

The following should be an example of an instruction that requires
zero-initialization:

/* S2_vsplatrh */
void emit_S2_vsplatrh(DisasContext *ctx, Insn *insn, Packet *pkt,
  TCGv_i64 RddV, TCGv_i32 RsV)
/*  for (i=0;i<4;i++) { fSETHALF(i,RddV, fGETHALF(0,RsV)); } } */
{
  tcg_gen_movi_i64(RddV, 0);
  for (int i = ((int64_t)0ULL); i < ((int64_t)4ULL); i++) {
TCGv_i32 tmp_0 = tcg_temp_new_i32();
tcg_gen_sextract_i32(tmp_0, RsV, ((int64_t)0ULL) * 16, 16);
TCGv_i64 tmp_1 = tcg_temp_new_i64();
tcg_gen_ext_i32_i64(tmp_1, tmp_0);
tcg_temp_free_i32(tmp_0);
tcg_gen_deposit_i64(RddV, RddV, tmp_1, i * 16, 16);
tcg_temp_free_i64(tmp_1);
  }
}

If we don't zero-initialize RddV, the deposit instruction will read
uninitialized data.

Note that, IIRC, `RddV` is not always a global variable, which could be
safely read, but it might be an uninitialized TCGv that will be
written to the CPU state in the commit phase.

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v2 08/10] target/hexagon: import parser for idef-parser

2021-03-01 Thread Alessandro Di Federico via
On Thu, 25 Feb 2021 19:30:14 -0800
Richard Henderson  wrote:

> > +}
> > +}
> > +code
> > +{
> > +if (c->inst.error_count != 0) {
> > +fprintf(stderr,
> > +"Parsing of instruction %s generated %d errors!\n",
> > +c->inst.name,
> > +c->inst.error_count);
> > +EMIT(c, "assert(false && \"This instruction is not
> > implemented!\");");  
> 
> What's the point of assert(false) above abort()?
> 
> Is there any point in emitting anything at all, since I assume the
> idef-parser program itself will exit with error, stopping the build
> process?

This is a leftover, that string will never be written to disk (`commit`
is not invoked).

> > +| pre ASSIGN rvalue
> > +{
> > +@1.last_column = @3.last_column;  
> 
> Do you really find any value in this column manipulation, given that
> the input is not the original file, but the output of cpp?

The output of `cpp` is quite readable. We use it a lot for debugging
and it's very helpful.

> IMO this is another reason to *not* preprocess with macros.inc, nor
> sed the output as a workaround for your parsing troubles.

Yes, `sed` is a workaround I really don't like too. But preprocessing
with `cpp` saves us from having to handle a larger, redundant language.
After all, the input language is designed to be expanded through the
preprocessor, although with a different set of macros. I'd keep that
part.

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v2 02/10] target/hexagon: import README for idef-parser

2021-03-01 Thread Alessandro Di Federico via
On Thu, 25 Feb 2021 12:20:53 -0800
Richard Henderson  wrote:
> This is odd, as is the description of why.  Yes, if RdV is read
> without initialization, TCG middle-end will abort (at least with
> --enable-debug-tcg enabling the assertions).  But you've just said
> that "no reading" was found.

When we say that no reading was found, we mean that it was not
initialized by the caller. The term "reading" is a leftover from how
the parser input was organized in the first iterations of the base
patchset.

I'll rephrase that.

> So why did you perform this dummy initialization, which will be
> eliminated later?

The initialization is redundant in this specific example, but, in
general, non-initialized values are assumed to be zero-initialized.
For instance when you're writing a 64-bit integer piecewise, by OR-ing
two 32-bit integers, it matters.

In short: useless in this case (but DCE'd by the mid-end), important in
general.
 
> So, I take it from this that you're emitting tcg directly from within
> the parser, and not generating any kind of abstract syntax tree?

Yes. There a few spots where an AST would have been beneficial, but
overall we deem it would increase the complexity of the parser with
limited return.

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH v2 09/10] target/hexagon: call idef-parser functions

2021-03-01 Thread Alessandro Di Federico via
On Thu, 25 Feb 2021 19:47:04 -0800
Richard Henderson  wrote:

> On 2/25/21 7:18 AM, Alessandro Di Federico wrote:
> > +elif hex_common.is_new_val(regtype, regid, tag):
> > +declared.append("%s%sN" % (regtype,regid))
> > +else:
> > +print("Bad register parse:",regtype,regid,toss,numregs)  
> 
> print, but nothing to force exit-with-failure, now or at a later
> date.  Just raise a python exception?

Yes, the whole error handling should be improved in the script.

Our goal was to get this patchset in and then do another pass to clean
up things later on. However, if you deem this is the proper time to
do it, we can go for it.

-- 
Alessandro Di Federico
rev.ng



Re: [PATCH 0/4] hexagon: Add Docker image & testing to gitlab-ci

2021-03-01 Thread Alessandro Di Federico via
On Sun, 28 Feb 2021 23:23:10 +0100
Philippe Mathieu-Daudé  wrote:

> This series is a rework of the 'Add Dockerfile for hexagon' patch
> from Alessandro/Brian that Taylor sent in v8:
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg780330.html
> but adapted to mainstream.

All of this looks good to me.

Sadly, we've been doing internally exactly the same thing and were close
to push it upstream. We'll be more explicit on what we're doing.

Anyway, thanks for taking care of this!

-- 
Alessandro Di Federico
rev.ng



[PATCH v2 10/10] target/hexagon: import additional tests

2021-02-25 Thread Alessandro Di Federico via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 tests/tcg/hexagon/Makefile.target  | 35 -
 tests/tcg/hexagon/crt.S| 28 +
 tests/tcg/hexagon/first.S  | 24 ++--
 tests/tcg/hexagon/test_abs.S   | 20 ++
 tests/tcg/hexagon/test_add.S   | 20 ++
 tests/tcg/hexagon/test_andp.S  | 23 +++
 tests/tcg/hexagon/test_bitcnt.S| 42 
 tests/tcg/hexagon/test_bitsplit.S  | 25 
 tests/tcg/hexagon/test_call.S  | 63 ++
 tests/tcg/hexagon/test_clobber.S   | 35 +
 tests/tcg/hexagon/test_cmp.S   | 34 
 tests/tcg/hexagon/test_cmpy.S  | 31 +++
 tests/tcg/hexagon/test_djump.S | 24 
 tests/tcg/hexagon/test_dotnew.S| 39 ++
 tests/tcg/hexagon/test_dstore.S| 29 ++
 tests/tcg/hexagon/test_ext.S   | 18 +
 tests/tcg/hexagon/test_fibonacci.S | 33 
 tests/tcg/hexagon/test_hello.S | 21 ++
 tests/tcg/hexagon/test_hl.S| 19 +
 tests/tcg/hexagon/test_hwloops.S   | 25 
 tests/tcg/hexagon/test_jmp.S   | 25 
 tests/tcg/hexagon/test_lsr.S   | 39 ++
 tests/tcg/hexagon/test_mpyi.S  | 20 ++
 tests/tcg/hexagon/test_packet.S| 26 
 tests/tcg/hexagon/test_reorder.S   | 31 +++
 tests/tcg/hexagon/test_round.S | 31 +++
 tests/tcg/hexagon/test_vavgw.S | 33 
 tests/tcg/hexagon/test_vcmpb.S | 32 +++
 tests/tcg/hexagon/test_vcmpw.S | 29 ++
 tests/tcg/hexagon/test_vcmpy.S | 50 
 tests/tcg/hexagon/test_vlsrw.S | 23 +++
 tests/tcg/hexagon/test_vmaxh.S | 37 ++
 tests/tcg/hexagon/test_vminh.S | 37 ++
 tests/tcg/hexagon/test_vpmpyh.S| 30 ++
 tests/tcg/hexagon/test_vspliceb.S  | 33 
 35 files changed, 1051 insertions(+), 13 deletions(-)
 create mode 100644 tests/tcg/hexagon/crt.S
 create mode 100644 tests/tcg/hexagon/test_abs.S
 create mode 100644 tests/tcg/hexagon/test_add.S
 create mode 100644 tests/tcg/hexagon/test_andp.S
 create mode 100644 tests/tcg/hexagon/test_bitcnt.S
 create mode 100644 tests/tcg/hexagon/test_bitsplit.S
 create mode 100644 tests/tcg/hexagon/test_call.S
 create mode 100644 tests/tcg/hexagon/test_clobber.S
 create mode 100644 tests/tcg/hexagon/test_cmp.S
 create mode 100644 tests/tcg/hexagon/test_cmpy.S
 create mode 100644 tests/tcg/hexagon/test_djump.S
 create mode 100644 tests/tcg/hexagon/test_dotnew.S
 create mode 100644 tests/tcg/hexagon/test_dstore.S
 create mode 100644 tests/tcg/hexagon/test_ext.S
 create mode 100644 tests/tcg/hexagon/test_fibonacci.S
 create mode 100644 tests/tcg/hexagon/test_hello.S
 create mode 100644 tests/tcg/hexagon/test_hl.S
 create mode 100644 tests/tcg/hexagon/test_hwloops.S
 create mode 100644 tests/tcg/hexagon/test_jmp.S
 create mode 100644 tests/tcg/hexagon/test_lsr.S
 create mode 100644 tests/tcg/hexagon/test_mpyi.S
 create mode 100644 tests/tcg/hexagon/test_packet.S
 create mode 100644 tests/tcg/hexagon/test_reorder.S
 create mode 100644 tests/tcg/hexagon/test_round.S
 create mode 100644 tests/tcg/hexagon/test_vavgw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpb.S
 create mode 100644 tests/tcg/hexagon/test_vcmpw.S
 create mode 100644 tests/tcg/hexagon/test_vcmpy.S
 create mode 100644 tests/tcg/hexagon/test_vlsrw.S
 create mode 100644 tests/tcg/hexagon/test_vmaxh.S
 create mode 100644 tests/tcg/hexagon/test_vminh.S
 create mode 100644 tests/tcg/hexagon/test_vpmpyh.S
 create mode 100644 tests/tcg/hexagon/test_vspliceb.S

diff --git a/tests/tcg/hexagon/Makefile.target 
b/tests/tcg/hexagon/Makefile.target
index 616af697fe..f4a774cda1 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -32,7 +32,7 @@ CFLAGS += -Wno-incompatible-pointer-types 
-Wno-undefined-internal
 HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon
 VPATH += $(HEX_SRC)
 
-first: $(HEX_SRC)/first.S
+%: $(HEX_SRC)/%.S $(HEX_SRC)/crt.S
$(CC) -static -mv67 -nostdlib $^ -o $@
 
 HEX_TESTS = first
@@ -43,4 +43,37 @@ HEX_TESTS += mem_noshuf
 HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_add
+HEX_TESTS += test_andp
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_call
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+HEX_TESTS += test_cmpy
+HEX_TESTS += test_djump
+HEX_TESTS += test_dotnew
+HEX_TESTS += test_dstore
+HEX_TESTS += test_ext
+HEX_TESTS += test_fibonacci
+HEX_TESTS += test_hello
+HEX_TESTS += test_hl
+HEX_TESTS += test_hwloops
+HEX_TESTS += test_jmp
+HEX_TESTS += test_lsr
+HEX_TESTS += test_mpyi
+HEX_TESTS += test_packet
+HEX_TESTS += test_reorder
+HEX_TESTS += test_round
+HEX_TESTS += test_vavgw
+HEX_TESTS += test_vcmpb
+

[PATCH v2 07/10] target/hexagon: import lexer for idef-parser

2021-02-25 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.h  | 245 +++
 target/hexagon/idef-parser/idef-parser.lex| 647 ++
 target/hexagon/meson.build|   4 +
 tests/docker/dockerfiles/alpine.docker|   1 +
 tests/docker/dockerfiles/centos7.docker   |   1 +
 tests/docker/dockerfiles/centos8.docker   |   1 +
 tests/docker/dockerfiles/debian10.docker  |   1 +
 .../dockerfiles/fedora-i386-cross.docker  |   1 +
 .../dockerfiles/fedora-win32-cross.docker |   1 +
 .../dockerfiles/fedora-win64-cross.docker |   1 +
 tests/docker/dockerfiles/fedora.docker|   1 +
 tests/docker/dockerfiles/opensuse-leap.docker |   1 +
 tests/docker/dockerfiles/ubuntu.docker|   1 +
 tests/docker/dockerfiles/ubuntu1804.docker|   1 +
 tests/docker/dockerfiles/ubuntu2004.docker|   3 +-
 15 files changed, 909 insertions(+), 1 deletion(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.h
 create mode 100644 target/hexagon/idef-parser/idef-parser.lex

diff --git a/target/hexagon/idef-parser/idef-parser.h 
b/target/hexagon/idef-parser/idef-parser.h
new file mode 100644
index 00..d08b9c80ea
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright(c) 2019-2020 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef IDEF_PARSER_H
+#define IDEF_PARSER_H
+
+#include 
+#include 
+#include 
+
+#define TCGV_NAME_SIZE 7
+#define MAX_WRITTEN_REGS 32
+#define OFFSET_STR_LEN 32
+#define ALLOC_LIST_LEN 32
+#define ALLOC_NAME_SIZE 32
+#define INIT_LIST_LEN 32
+#define OUT_BUF_LEN (1024 * 1024)
+#define SIGNATURE_BUF_LEN (128 * 1024)
+#define HEADER_BUF_LEN (128 * 1024)
+
+/* Variadic macros to wrap the buffer printing functions */
+#define EMIT(c, ...) \
+do { \
+(c)->out_c += snprintf((c)->out_buffer + (c)->out_c, \
+   OUT_BUF_LEN - (c)->out_c, \
+   __VA_ARGS__); \
+} while (0)
+
+#define EMIT_SIG(c, ...)   
\
+do {   
\
+(c)->signature_c += snprintf((c)->signature_buffer + (c)->signature_c, 
\
+ SIGNATURE_BUF_LEN - (c)->signature_c, 
\
+ __VA_ARGS__); 
\
+} while (0)
+
+#define EMIT_HEAD(c, ...)  
\
+do {   
\
+(c)->header_c += snprintf((c)->header_buffer + (c)->header_c,  
\
+ SIGNATURE_BUF_LEN - (c)->header_c,
\
+ __VA_ARGS__); 
\
+} while (0)
+
+/**
+ * Type of register, assigned to the HexReg.type field
+ */
+typedef enum {GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW} RegType;
+
+/**
+ * Types of control registers, assigned to the HexReg.id field
+ */
+typedef enum {SP, FP, LR, GP, LC0, LC1, SA0, SA1} CregType;
+
+/**
+ * Identifier string of the control registers, indexed by the CregType enum
+ */
+extern const char *creg_str[];
+
+/**
+ * Semantic record of the REG tokens, identifying registers
+ */
+typedef struct HexReg {
+CregType id;/**< Identifier of the register  */
+RegType type;   /**< Type of the register*/
+unsigned bit_width; /**< Bit width of the reg, 32 or 64 bits */
+} HexReg;
+
+/**
+ * Data structure, identifying a TCGv temporary value
+ */
+typedef struct HexTmp {
+int index;  /**< Index of the TCGv temporary value*/
+} HexTmp;
+
+/**
+ * Enum of the possible immediated, an immediate is a value which is known
+ * at tinycode generation time, e.g. an integer value, not a TCGv
+ */
+enum ImmUnionTag {I, VARIABLE, VALUE, QEMU_TMP, IMM_PC, IMM_CONSTEXT};
+
+/**
+ * Semantic record of the IMM token, identifying an immediate constant
+ */
+t

Re: [RFC PATCH 00/10] target/hexagon: introduce idef-parser

2021-02-25 Thread Alessandro Di Federico via
On Sun, 14 Feb 2021 13:52:25 -0800
Richard Henderson  wrote:

> Well, first off, this fails to build with our gitlab CI.
> 
> There are several problems, apart from the new bison parse.error
> option previously reported:
> 
> (1) bison and flex not added to dockerfiles, so the packages are not
> available to CI.
> 
> (2) idef-parser program not marked with "native: true", so we get an
> early meson error about that.
> 
> (3) flex = generator() does not specify both output files, so the
> proper dependency on idef-parser.yy.h is not present.
> 
> (4) idef-parser.yy.h is placed in the wrong directory, because you
> used '%option header-file="xyz"' instead of the command-line
> '--headerfile=@OUTPUT1@'.  This results in an immediate compilation
> failure, because the file isn't found.
> 
> (5) There's an odd mismatch in file naming, in which you have
> idef-lexer.lex.yy.c but idef-parser.yy.h.  Not a bug, really, but it
> looks odd when fixing 3 & 4.

We've integrated the suggested changes and tested the v2 on the Gitlab
CI. It should now work properly.

-- 
Alessandro Di Federico
rev.ng



Re: [RFC PATCH 08/10] target/hexagon: import parser for idef-parser

2021-02-25 Thread Alessandro Di Federico via
On Sun, 14 Feb 2021 08:56:11 -0800
Richard Henderson  wrote:

> What version of bison are you using?

We were using a rather recent version of bison (3.7.5), but it's not
strictly required.

Fixed in v2.

-- 
Alessandro Di Federico
rev.ng



[PATCH v2 08/10] target/hexagon: import parser for idef-parser

2021-02-25 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/idef-parser/idef-parser.y  | 1250 +++
 target/hexagon/idef-parser/parser-helpers.c   | 1925 +
 target/hexagon/idef-parser/parser-helpers.h   |  293 +++
 target/hexagon/meson.build|   23 +-
 tests/docker/dockerfiles/alpine.docker|1 +
 tests/docker/dockerfiles/centos7.docker   |1 +
 tests/docker/dockerfiles/centos8.docker   |1 +
 tests/docker/dockerfiles/debian10.docker  |1 +
 .../dockerfiles/fedora-i386-cross.docker  |1 +
 .../dockerfiles/fedora-win32-cross.docker |1 +
 .../dockerfiles/fedora-win64-cross.docker |1 +
 tests/docker/dockerfiles/fedora.docker|1 +
 tests/docker/dockerfiles/opensuse-leap.docker |1 +
 tests/docker/dockerfiles/ubuntu.docker|1 +
 tests/docker/dockerfiles/ubuntu1804.docker|1 +
 tests/docker/dockerfiles/ubuntu2004.docker|3 +-
 16 files changed, 3503 insertions(+), 2 deletions(-)
 create mode 100644 target/hexagon/idef-parser/idef-parser.y
 create mode 100644 target/hexagon/idef-parser/parser-helpers.c
 create mode 100644 target/hexagon/idef-parser/parser-helpers.h

diff --git a/target/hexagon/idef-parser/idef-parser.y 
b/target/hexagon/idef-parser/idef-parser.y
new file mode 100644
index 00..d9dd81bd6f
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,1250 @@
+%{
+/*
+ * Copyright(c) 2019-2020 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; withOUT even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "idef-parser.h"
+#include "parser-helpers.h"
+#include "idef-parser.tab.h"
+#include "idef-parser.yy.h"
+
+/* Uncomment this to disable yyasserts */
+/* #define NDEBUG */
+
+#define ERR_LINE_CONTEXT 40
+
+%}
+
+%lex-param {void *scanner}
+%parse-param {void *scanner}
+%parse-param {Context *c}
+
+/* Uncomment this for better errors in recent bison versions */
+/* %define parse.error detailed */
+%define parse.error verbose
+%define parse.lac full
+%define api.pure full
+
+%locations
+
+%union {
+char *string;
+HexValue rvalue;
+HexSat sat;
+HexCast cast;
+HexExtract extract;
+HexMpy mpy;
+bool is_unsigned;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token INAME DREG DIMM DPRE DEA RREG WREG FREG FIMM RPRE WPRE FPRE FWRAP FEA
+%token VAR LBR RBR LPAR RPAR LSQ RSQ SEMI COLON PLUS MINUS MUL POW DIV MOD ABS
+%token CROUND ROUND CIRCADD COUNTONES AND OR XOR NOT ASSIGN INC DEC ANDA ORA
+%token XORA PLUSPLUS LT GT ASL ASR LSR EQ NEQ LTE GTE MIN MAX ANDL ORL NOTL
+%token COMMA FOR ICIRC IF MUN FSCR FCHK SXT ZXT NEW CONSTEXT LOCNT BREV SIGN
+%token LOAD STORE CONSTLL CONSTULL PC NPC LPCFG CANC QMARK IDENTITY PART1
+%token BREV_4 BREV_8 ROTL INSBITS SETBITS EXTBITS EXTRANGE CAST4_8U SETOVF FAIL
+%token DEINTERLEAVE INTERLEAVE
+
+%token  REG IMM PRE
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement pre
+%type  DREG DIMM DPRE RREG RPRE FAIL
+%type  if_stmt IF
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left LPAR
+%left COMMA
+%left ASSIGN
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left QMARK COLON
+%left ORL
+%left ANDL
+%left OR
+%left XOR ANDOR
+%left AND
+%left EQ NEQ
+%left LT GT LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left MINUS PLUS
+%left POW
+%left MUL DIV MOD MPY
+%right NOT NOTL
+%left LSQ
+%left NEW
+%right CAST
+%right LOCNT BREV
+
+/* Bison Grammar */
+%%
+
+/* Input file containing the description of each hexagon instruction */
+input : instructions
+{
+YYACCEPT;
+}
+;
+
+instructions : instruction instructions
+| %empty
+;
+
+instruction : INAME
+{
+/* Early-free if the parser failed on the previous instruction */
+free_instruction(c);
+
+c->total_insn++;
+c->inst.name = $1;
+emit_header(c);
+}
+arguments
+{
+EMIT_SIG(c, ")");
+EMIT_HEAD(c, "{\n");
+
+/* Initialize declared but uninitialized registers, but only for */
+/* non-conditional instructions */
+for (int i = 0; i < c->inst.init_count; i++) {
+bool is64 = c->inst.init_list[i].bit_width == 64;
+const char *type = is64 ? "i64" : "i32";
+if (c->inst.init_list[i].type == REGISTER) {
+OUT(c,

[PATCH v2 02/10] target/hexagon: import README for idef-parser

2021-02-25 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/README |   5 +
 target/hexagon/idef-parser/README.rst | 447 ++
 2 files changed, 452 insertions(+)
 create mode 100644 target/hexagon/idef-parser/README.rst

diff --git a/target/hexagon/README b/target/hexagon/README
index b0b2435070..2f2814380c 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -23,6 +23,10 @@ Hexagon-specific code are
 encode*.def Encoding patterns for each instruction
 iclass.def  Instruction class definitions used to determine
 legal VLIW slots for each instruction
+qemu/target/hexagon/idef-parser
+Parser that, given the high-level definitions of an instruction,
+produces a C function generating equivalent tiny code instructions.
+See README.rst.
 qemu/linux-user/hexagon
 Helpers for loading the ELF file and making Linux system calls,
 signals, etc
@@ -43,6 +47,7 @@ header files in /target/hexagon
 gen_tcg_funcs.py-> tcg_funcs_generated.c.inc
 gen_tcg_func_table.py   -> tcg_func_table_generated.c.inc
 gen_helper_funcs.py -> helper_funcs_generated.c.inc
+gen_idef_parser_funcs.py-> idef_parser_input.h
 
 Qemu helper functions have 3 parts
 DEF_HELPER declaration indicates the signature of the helper
diff --git a/target/hexagon/idef-parser/README.rst 
b/target/hexagon/idef-parser/README.rst
new file mode 100644
index 00..95377cc7e0
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,447 @@
+Hexagon ISA instruction definitions to tinycode generator compiler
+--
+
+idef-parser is a small compiler able to translate the Hexagon ISA description
+language into tinycode generator code, that can be easily integrated into QEMU.
+
+Compilation Example
+---
+
+To better understand the scope of the idef-parser, we'll explore an applicative
+example. Let's start by one of the simplest Hexagon instruction: the ``add``.
+
+The ISA description language represents the ``add`` instruction as
+follows:
+
+.. code:: c
+
+   A2_add(RdV, in RsV, in RtV) {
+   { RdV=RsV+RtV;}
+   }
+
+idef-parser will compile the above code into the following code:
+
+.. code:: c
+
+   /* A2_add */
+   void emit_A2_add(DisasContext *ctx, Insn *insn, Packet *pkt, TCGv_i32 RdV,
+TCGv_i32 RsV, TCGv_i32 RtV)
+   /*  { RdV=RsV+RtV;} */
+   {
+   tcg_gen_movi_i32(RdV, 0);
+   TCGv_i32 tmp_0 = tcg_temp_new_i32();
+   tcg_gen_add_i32(tmp_0, RsV, RtV);
+   tcg_gen_mov_i32(RdV, tmp_0);
+   tcg_temp_free_i32(tmp_0);
+   }
+
+The output of the compilation process will be a function, containing the
+tinycode generator code, implementing the correct semantics. That function will
+not access any global variable, because all the accessed data structures will 
be
+passed explicitly as function parameters. Among the passed parameters we will
+have TCGv (tinycode variables) representing the input and output registers of
+the architecture, integers representing the immediates that come from the code,
+and other data structures which hold information about the disassemblation
+context (``DisasContext`` struct).
+
+Let's begin by describing the input code. The ``add`` instruction is associated
+with a unique identifier, in this case ``A2_add``, which allows to distinguish
+variants of the same instruction, and expresses the class to which the
+instruction belongs, in this case ``A2`` corresponds to the Hexagon
+``ALU32/ALU`` instruction subclass.
+
+After the instruction identifier, we have a series of parameters that 
represents
+TCG variables that will be passed to the generated function. Parameters marked
+with ``in`` are already initialized, while the others are output parameters.
+
+We will leverage this information to infer several information:
+
+-  Fill in the output function signature with the correct TCGv registers
+-  Fill in the output function signature with the immediate integers
+-  Keep track of which registers, among the declared one, have been
+   initialized
+
+Let's now observe the actual instruction description code, in this case:
+
+.. code:: c
+
+   { RdV=RsV+RtV;}
+
+This code is composed by a subset of the C syntax, and is the result of the
+application of some macro definitions contained in the ``macros.h`` file.
+
+This file is used to reduce the complexity of the input language where complex
+variants of similar constructs can be mapped to a unique primitive, so that the
+idef-parser has to handle a lower number of computation primitives.
+
+As you may notice, the description code modifies the registers which have been
+declared by the declaration statements. In this case all the three registers
+will be declared, ``RsV`` and ``RtV`` wil

[PATCH v2 09/10] target/hexagon: call idef-parser functions

2021-02-25 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Extend gen_tcg_funcs.py in order to emit calls to the functions emitted
by the idef-parser, if available.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_tcg_funcs.py | 28 ++--
 target/hexagon/hex_common.py| 10 ++
 target/hexagon/meson.build  | 24 ++--
 3 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index fe4d8e5730..c3f04949a0 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -394,7 +394,29 @@ def gen_tcg_func(f, tag, regs, imms):
 if (hex_common.is_read(regid)):
 genptr_src_read_opn(f,regtype,regid,tag)
 
-if ( hex_common.skip_qemu_helper(tag) ):
+if hex_common.is_idef_parser_enabled(tag):
+declared = []
+## Handle registers
+for regtype,regid,toss,numregs in regs:
+if (hex_common.is_pair(regid)
+or (hex_common.is_single(regid)
+and hex_common.is_old_val(regtype, regid, tag))):
+declared.append("%s%sV" % (regtype, regid))
+if regtype == "M":
+declared.append("%s%sN" % (regtype, regid))
+elif hex_common.is_new_val(regtype, regid, tag):
+declared.append("%s%sN" % (regtype,regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+## Handle immediates
+for immlett,bits,immshift in imms:
+declared.append(hex_common.imm_name(immlett))
+
+arguments = ", ".join(["ctx", "insn", "pkt"] + declared)
+f.write("emit_%s(%s);\n" % (tag, arguments))
+
+elif ( hex_common.skip_qemu_helper(tag) ):
 f.write("fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
 else:
 ## Generate the call to the helper
@@ -455,12 +477,14 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.calculate_attribs()
+hex_common.read_idef_parser_enabled_file(sys.argv[4])
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[4], 'w') as f:
+with open(sys.argv[5], 'w') as f:
 f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
 f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
+f.write("#include \"idef-generated-emitter.h.inc\"\n\n")
 
 for tag in hex_common.tags:
 ## Skip the priv instructions
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index b3b534057d..648ad29e94 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -28,6 +28,7 @@
 attribinfo = {}   # Register information and misc
 tags = [] # list of all tags
 overrides = {}# tags with helper overrides
+idef_parser_enabled = {} # tags enabled for idef-parser
 
 # We should do this as a hash for performance,
 # but to keep order let's keep it as a list.
@@ -201,6 +202,9 @@ def need_ea(tag):
 def skip_qemu_helper(tag):
 return tag in overrides.keys()
 
+def is_idef_parser_enabled(tag):
+return tag in idef_parser_enabled
+
 def imm_name(immlett):
 return "%siV" % immlett
 
@@ -232,3 +236,9 @@ def read_overrides_file(name):
 continue
 tag = overridere.findall(line)[0]
 overrides[tag] = True
+
+def read_idef_parser_enabled_file(name):
+global idef_parser_enabled
+with open(name, "r") as idef_parser_enabled_file:
+lines = idef_parser_enabled_file.read().strip().split("\n")
+idef_parser_enabled = set(lines)
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index e6abcc472f..8809954883 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -72,16 +72,6 @@ helper_protos_generated = custom_target(
 )
 hexagon_ss.add(helper_protos_generated)
 
-tcg_funcs_generated = custom_target(
-'tcg_funcs_generated.c.inc',
-output: 'tcg_funcs_generated.c.inc',
-input: 'gen_tcg_funcs.py',
-depends: [semantics_generated],
-depend_files: [hex_common_py, attribs_def, gen_tcg_h],
-command: [python, '@INPUT@', semantics_generated, attribs_def, gen_tcg_h, 
'@OUTPUT@'],
-)
-hexagon_ss.add(tcg_funcs_generated)
-
 tcg_func_table_generated = custom_target(
 'tcg_func_table_generated.c.inc',
 output: 'tcg_func_table_generated.c.inc',
@@ -231,4 +221,18 @@ idef_generated_tcg = custom_target(
 command: [idef_parser, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@', '@OUTPUT2@'],
 )
 
+idef_generated_list = idef_generated_tcg[2].full_path()
+
+hexagon_ss.add(idef_generated_tcg)
+
+tcg_funcs_generated = custom_target(
+'tcg_funcs_generated.c.inc',
+output: 'tcg_funcs_generated.c.inc',
+input: 'gen_tcg_funcs.py',
+depends: [semantics_generated, idef_generated_tcg],
+depend_files: [hex_common_py, attribs_def, gen_tcg_h],
+command: [pytho

[PATCH v2 05/10] target/hexagon: expose next PC in DisasContext

2021-02-25 Thread Alessandro Di Federico via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/translate.c | 4 +++-
 target/hexagon/translate.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index eeaad5f8ba..a59db485a3 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -503,11 +503,13 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, &pkt, false) > 0) {
 HEX_DEBUG_PRINT_PKT(&pkt);
 gen_start_packet(ctx, &pkt);
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, &pkt.insn[i], &pkt);
 }
 gen_commit_packet(ctx, &pkt);
-ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
+ctx->base.pc_next = ctx->npc;
+ctx->npc = 0;
 } else {
 gen_exception(HEX_EXCP_INVALID_PACKET);
 ctx->base.is_jmp = DISAS_NORETURN;
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 938f7fbb9f..2195e20f4b 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -36,6 +36,7 @@ typedef struct DisasContext {
 int preg_log_idx;
 uint8_t store_width[STORES_MAX];
 uint8_t s1_store_processed;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.30.1




[PATCH v2 04/10] target/hexagon: introduce new helper functions

2021-02-25 Thread Alessandro Di Federico via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
---
 target/hexagon/genptr.c | 227 +++-
 target/hexagon/genptr.h |  19 
 target/hexagon/macros.h |   2 +-
 3 files changed, 245 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 97de669f38..78cda032db 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -40,7 +40,8 @@ TCGv gen_read_preg(TCGv pred, uint8_t num)
 return pred;
 }
 
-static inline void gen_log_predicated_reg_write(int rnum, TCGv val, int slot)
+static inline void gen_log_predicated_reg_write(int rnum, TCGv val,
+unsigned slot)
 {
 TCGv one = tcg_const_tl(1);
 TCGv zero = tcg_const_tl(0);
@@ -69,7 +70,8 @@ void gen_log_reg_write(int rnum, TCGv val)
 #endif
 }
 
-static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val, int slot)
+static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val,
+  unsigned slot)
 {
 TCGv val32 = tcg_temp_new();
 TCGv one = tcg_const_tl(1);
@@ -334,5 +336,226 @@ static inline void gen_store_conditional8(CPUHexagonState 
*env,
 tcg_gen_movi_tl(hex_llsc_addr, ~0);
 }
 
+void gen_fbrev(TCGv result, TCGv src)
+{
+TCGv lo = tcg_temp_new();
+TCGv tmp1 = tcg_temp_new();
+TCGv tmp2 = tcg_temp_new();
+
+/* Bit reversal of low 16 bits */
+tcg_gen_extract_tl(lo, src, 0, 16);
+tcg_gen_andi_tl(tmp1, lo, 0x);
+tcg_gen_shri_tl(tmp1, tmp1, 1);
+tcg_gen_andi_tl(tmp2, lo, 0x);
+tcg_gen_shli_tl(tmp2, tmp2, 1);
+tcg_gen_or_tl(lo, tmp1, tmp2);
+tcg_gen_andi_tl(tmp1, lo, 0x);
+tcg_gen_shri_tl(tmp1, tmp1, 2);
+tcg_gen_andi_tl(tmp2, lo, 0x);
+tcg_gen_shli_tl(tmp2, tmp2, 2);
+tcg_gen_or_tl(lo, tmp1, tmp2);
+tcg_gen_andi_tl(tmp1, lo, 0xf0f0);
+tcg_gen_shri_tl(tmp1, tmp1, 4);
+tcg_gen_andi_tl(tmp2, lo, 0x0f0f);
+tcg_gen_shli_tl(tmp2, tmp2, 4);
+tcg_gen_or_tl(lo, tmp1, tmp2);
+tcg_gen_bswap16_tl(lo, lo);
+
+/* Final tweaks */
+tcg_gen_extract_tl(result, src, 16, 16);
+tcg_gen_or_tl(result, result, lo);
+
+tcg_temp_free(lo);
+tcg_temp_free(tmp1);
+tcg_temp_free(tmp2);
+}
+
+TCGv gen_set_bit(tcg_target_long i, TCGv result, TCGv src)
+{
+TCGv mask = tcg_const_tl(~(1 << i));
+TCGv bit = tcg_temp_new();
+tcg_gen_shli_tl(bit, src, i);
+tcg_gen_and_tl(result, result, mask);
+tcg_gen_or_tl(result, result, bit);
+tcg_temp_free(mask);
+tcg_temp_free(bit);
+
+return result;
+}
+
+void gen_cancel(tcg_target_ulong slot)
+{
+TCGv one = tcg_const_tl(1);
+tcg_gen_deposit_tl(hex_slot_cancelled, hex_slot_cancelled, one, slot, 1);
+tcg_temp_free(one);
+}
+
+void gen_store32(TCGv vaddr, TCGv src, tcg_target_long width, unsigned slot)
+{
+tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
+tcg_gen_movi_tl(hex_store_width[slot], width);
+tcg_gen_mov_tl(hex_store_val32[slot], src);
+}
+
+void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 1, slot);
+ctx->store_width[slot] = 1;
+}
+
+void gen_store2(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 2, slot);
+ctx->store_width[slot] = 2;
+}
+
+void gen_store4(TCGv_env cpu_env, TCGv vaddr, TCGv src, DisasContext *ctx,
+unsigned slot)
+{
+gen_store32(vaddr, src, 4, slot);
+ctx->store_width[slot] = 4;
+}
+
+
+void gen_store8(TCGv_env cpu_env, TCGv vaddr, TCGv_i64 src, DisasContext *ctx,
+unsigned slot)
+{
+tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
+tcg_gen_movi_tl(hex_store_width[slot], 8);
+tcg_gen_mov_i64(hex_store_val64[slot], src);
+ctx->store_width[slot] = 8;
+}
+
+void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_gpr[HEX_REG_USR], hex_gpr[HEX_REG_USR], val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+}
+
+void gen_set_usr_fieldi(int field, int x)
+{
+TCGv val = tcg_const_tl(x);
+gen_set_usr_field(field, val);
+tcg_temp_free(val);
+}
+
+void gen_write_new_pc(TCGv addr)
+{
+/* If there are multiple branches in a packet, ignore the second one */
+TCGv zero = tcg_const_tl(0);
+tcg_gen_movcond_tl(TCG_COND_NE, hex_next_PC, hex_branch_taken, zero,
+   hex_next_PC, addr);
+tcg_gen_movi_tl(hex_branch_taken, 1);
+tcg_temp_free(zero);
+}
+
+void gen_sat_i32(TCGv dest, TCGv source, int width, bool set_overflow)
+{
+TCGv max_val = tcg_const_i32((1 << (width - 1)) - 1);
+TCGv min_val = tcg_const_i32(-(1 << (width - 1)));
+tcg_gen_movcond_i32(TCG_COND_GT, dest, source, max_val, max_val, source)

[PATCH v2 06/10] target/hexagon: prepare input for the idef-parser

2021-02-25 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Introduce infrastructure necessary to produce a file suitable for being
parsed by the idef-parser.

Signed-off-by: Alessandro Di Federico 
---
 target/hexagon/gen_idef_parser_funcs.py | 114 
 target/hexagon/idef-parser/macros.inc   | 166 
 target/hexagon/idef-parser/prepare  |  33 +
 target/hexagon/meson.build  |  18 +++
 4 files changed, 331 insertions(+)
 create mode 100644 target/hexagon/gen_idef_parser_funcs.py
 create mode 100644 target/hexagon/idef-parser/macros.inc
 create mode 100755 target/hexagon/idef-parser/prepare

diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
new file mode 100644
index 00..6fb3659201
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2020 rev.ng Srls. All Rights Reserved.
+##
+##  This program 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.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, see .
+##
+
+import sys
+import re
+import string
+from io import StringIO
+
+import hex_common
+
+##
+## Generate code to be fed to the idef_parser
+##
+## Consider A2_add:
+##
+## Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
+##
+## We produce:
+##
+## A2_add(RdV, in RsV, in RtV) {
+##   { RdV=RsV+RtV;}
+## }
+##
+## A2_add represents the instruction tag. Then we have a list of TCGv
+## that the code generated by the parser can expect in input. Some of
+## them are inputs ("in" prefix), while some others are outputs.
+##
+def main():
+hex_common.read_semantics_file(sys.argv[1])
+hex_common.read_attribs_file(sys.argv[2])
+hex_common.read_overrides_file(sys.argv[3])
+hex_common.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[4], 'w') as f:
+f.write('#include "macros.inc"\n\n')
+
+for tag in hex_common.tags:
+## Skip the priv instructions
+if ( "A_PRIV" in hex_common.attribdict[tag] ) :
+continue
+## Skip the guest instructions
+if ( "A_GUEST" in hex_common.attribdict[tag] ) :
+continue
+## Skip instructions using switch
+if ( tag in {'S4_vrcrotate_acc', 'S4_vrcrotate'} ) :
+continue
+## Skip trap instructions
+if ( tag in {'J2_trap0', 'J2_trap1'} ) :
+continue
+## Skip 128-bit instructions
+if ( tag in {'A7_croundd_ri', 'A7_croundd_rr'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag.startswith('S2_cabacdecbin') ) :
+continue
+if ( tag.startswith('Y') ) :
+continue
+if ( tag.startswith('V6_') ) :
+continue
+if ( tag.startswith('F') ) :
+continue
+if ( tag.endswith('_locked') ) :
+continue
+
+regs = tagregs[tag]
+imms = tagimms[tag]
+
+arguments = []
+if hex_common.need_ea(tag):
+arguments.append("EA")
+
+for regtype,regid,toss,numregs in regs:
+prefix = "in " if hex_common.is_read(regid) else ""
+
+is_pair = hex_common.is_pair(regid)
+is_single_old = (hex_common.is_single(regid)
+ and hex_common.is_old_val(regtype, regid, 
tag))
+is_single_new = (hex_common.is_single(regid)
+ and hex_common.is_new_val(regtype, regid, 
tag))
+
+if is_pair or is_single_old:
+arguments.append("%s%s%sV" % (prefix, regtype, regid))
+elif is_single_new:
+arguments.append("%s%s%sN" % (prefix, regtype, regid))
+else:
+print("Bad register parse: ",regtype,regid,toss,numregs)
+
+for immlett,bits,immshift in imms:
+arguments.append(hex_common.imm_name(immlett))
+
+f.write("%s(%s) {\n" % (tag, ", ".join(arguments)))
+f.write("%s\n" % hex_common.semdict[tag])
+f.write("}\n\n")
+
+if __name__ == "__main__":
+main()
diff --git a/target/hexagon/idef-parser/macros.inc 
b/target/hexagon/idef-parser/macros.inc
new 

[PATCH v2 01/10] target/hexagon: update MAINTAINERS for idef-parser

2021-02-25 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9b2aa18e1f..9a6878b970 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -192,11 +192,19 @@ Hexagon TCG CPUs
 M: Taylor Simpson 
 S: Supported
 F: target/hexagon/
+X: target/hexagon/idef-parser/
+X: target/hexagon/gen_idef_parser_funcs.py
 F: linux-user/hexagon/
 F: tests/tcg/hexagon/
 F: disas/hexagon.c
 F: default-configs/targets/hexagon-linux-user.mak
 
+Hexagon idef-parser
+M: Alessandro Di Federico 
+S: Supported
+F: target/hexagon/idef-parser/
+F: target/hexagon/gen_idef_parser_funcs.py
+
 HPPA (PA-RISC) TCG CPUs
 M: Richard Henderson 
 S: Maintained
-- 
2.30.1




[PATCH v2 00/10] target/hexagon: introduce idef-parser

2021-02-25 Thread Alessandro Di Federico via
From: Alessandro Di Federico 

This patchset introduces the idef-parser for target/hexagon.

It's the second iteration of the patchset and includes fixes suggested
in the previous iteration.

`idef-parser` is a build-time tool built using flex and bison. Its aim
is to generate a large part of the tiny code generator frontend for
Hexagon. The prototype of idef-parser has been presented at KVM Forum
2019 ("QEMU-Hexagon: Automatic Translation of the ISA Manual Pseudcode
to Tiny Code Instructions"):

https://www.youtube.com/watch?v=3EpnTYBOXCI

`target/hexagon/idef-parser/README.rst` provides an overview of the
parser and its inner working.

A couple of notes:

* `idef-parser` also supports certain things that are not used in the
  most recently submitted version of the "Hexagon patch
  series". However, they will be needed and stripping them out of the
  parser is quite a bit of work.
* checkpatch.pl complains on a single macro which has a trailing
  semi-colon, which is required.

Alessandro Di Federico (4):
  target/hexagon: update MAINTAINERS for idef-parser
  target/hexagon: import README for idef-parser
  target/hexagon: prepare input for the idef-parser
  target/hexagon: call idef-parser functions

Niccolò Izzo (2):
  target/hexagon: introduce new helper functions
  target/hexagon: import additional tests

Paolo Montesel (4):
  target/hexagon: make helper functions non-static
  target/hexagon: expose next PC in DisasContext
  target/hexagon: import lexer for idef-parser
  target/hexagon: import parser for idef-parser

 MAINTAINERS   |8 +
 target/hexagon/README |5 +
 target/hexagon/gen_idef_parser_funcs.py   |  114 +
 target/hexagon/gen_tcg_funcs.py   |   28 +-
 target/hexagon/genptr.c   |  240 +-
 target/hexagon/genptr.h   |   26 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  447 
 target/hexagon/idef-parser/idef-parser.h  |  245 +++
 target/hexagon/idef-parser/idef-parser.lex|  647 ++
 target/hexagon/idef-parser/idef-parser.y  | 1250 +++
 target/hexagon/idef-parser/macros.inc |  166 ++
 target/hexagon/idef-parser/parser-helpers.c   | 1925 +
 target/hexagon/idef-parser/parser-helpers.h   |  293 +++
 target/hexagon/idef-parser/prepare|   33 +
 target/hexagon/macros.h   |2 +-
 target/hexagon/meson.build|   67 +-
 target/hexagon/translate.c|4 +-
 target/hexagon/translate.h|1 +
 tests/docker/dockerfiles/alpine.docker|2 +
 tests/docker/dockerfiles/centos7.docker   |2 +
 tests/docker/dockerfiles/centos8.docker   |2 +
 tests/docker/dockerfiles/debian10.docker  |2 +
 .../dockerfiles/fedora-i386-cross.docker  |2 +
 .../dockerfiles/fedora-win32-cross.docker |2 +
 .../dockerfiles/fedora-win64-cross.docker |2 +
 tests/docker/dockerfiles/fedora.docker|2 +
 tests/docker/dockerfiles/opensuse-leap.docker |2 +
 tests/docker/dockerfiles/ubuntu.docker|2 +
 tests/docker/dockerfiles/ubuntu1804.docker|2 +
 tests/docker/dockerfiles/ubuntu2004.docker|4 +-
 tests/tcg/hexagon/Makefile.target |   35 +-
 tests/tcg/hexagon/crt.S   |   28 +
 tests/tcg/hexagon/first.S |   24 +-
 tests/tcg/hexagon/test_abs.S  |   20 +
 tests/tcg/hexagon/test_add.S  |   20 +
 tests/tcg/hexagon/test_andp.S |   23 +
 tests/tcg/hexagon/test_bitcnt.S   |   42 +
 tests/tcg/hexagon/test_bitsplit.S |   25 +
 tests/tcg/hexagon/test_call.S |   63 +
 tests/tcg/hexagon/test_clobber.S  |   35 +
 tests/tcg/hexagon/test_cmp.S  |   34 +
 tests/tcg/hexagon/test_cmpy.S |   31 +
 tests/tcg/hexagon/test_djump.S|   24 +
 tests/tcg/hexagon/test_dotnew.S   |   39 +
 tests/tcg/hexagon/test_dstore.S   |   29 +
 tests/tcg/hexagon/test_ext.S  |   18 +
 tests/tcg/hexagon/test_fibonacci.S|   33 +
 tests/tcg/hexagon/test_hello.S|   21 +
 tests/tcg/hexagon/test_hl.S   |   19 +
 tests/tcg/hexagon/test_hwloops.S  |   25 +
 tests/tcg/hexagon/test_jmp.S  |   25 +
 tests/tcg/hexagon/test_lsr.S  |   39 +
 tests/tcg/hexagon/test_mpyi.S |   20 +
 tests/tcg/hexagon/test_packet.S   |   26 +
 tests/tcg/hexagon/test_reorder.S  |   31 +
 tests/tcg/hexagon/test_round.S|   31 +
 tests/tcg/hexagon/test_vavgw.S|   33 +
 tests/tcg/hexagon/test_vcmpb.S|   32 +
 tests/tcg/hexagon/test_vcmpw.S|   29 +
 tests/tcg/hexagon/test_vcmpy.S  

[PATCH v2 03/10] target/hexagon: make helper functions non-static

2021-02-25 Thread Alessandro Di Federico via
From: Paolo Montesel 

Make certain helper functions non-static, making them available outside
genptr.c. These functions are required by code generated by the
idef-parser.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
---
 target/hexagon/genptr.c | 13 ++---
 target/hexagon/genptr.h |  7 +++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 7481f4c1dd..97de669f38 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -26,8 +26,15 @@
 #include "translate.h"
 #include "macros.h"
 #include "gen_tcg.h"
+#include "genptr.h"
 
-static inline TCGv gen_read_preg(TCGv pred, uint8_t num)
+TCGv gen_read_reg(TCGv result, int num)
+{
+tcg_gen_mov_tl(result, hex_gpr[num]);
+return result;
+}
+
+TCGv gen_read_preg(TCGv pred, uint8_t num)
 {
 tcg_gen_mov_tl(pred, hex_pred[num]);
 return pred;
@@ -53,7 +60,7 @@ static inline void gen_log_predicated_reg_write(int rnum, 
TCGv val, int slot)
 tcg_temp_free(slot_mask);
 }
 
-static inline void gen_log_reg_write(int rnum, TCGv val)
+void gen_log_reg_write(int rnum, TCGv val)
 {
 tcg_gen_mov_tl(hex_new_value[rnum], val);
 #if HEX_DEBUG
@@ -116,7 +123,7 @@ static void gen_log_reg_write_pair(int rnum, TCGv_i64 val)
 #endif
 }
 
-static inline void gen_log_pred_write(int pnum, TCGv val)
+void gen_log_pred_write(int pnum, TCGv val)
 {
 TCGv zero = tcg_const_tl(0);
 TCGv base_val = tcg_temp_new();
diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h
index c158005d2a..0bfa99b463 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -19,7 +19,14 @@
 #define HEXAGON_GENPTR_H
 
 #include "insn.h"
+#include "tcg/tcg.h"
+#include "translate.h"
 
 extern const SemanticInsn opcode_genptr[];
 
+TCGv gen_read_reg(TCGv result, int num);
+TCGv gen_read_preg(TCGv pred, uint8_t num);
+void gen_log_reg_write(int rnum, TCGv val);
+void gen_log_pred_write(int pnum, TCGv val);
+
 #endif
-- 
2.30.1




  1   2   >