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

2021-10-18 Thread Anton Johansson via

On 9/7/21 18:08, Taylor Simpson wrote:


+HexValue gen_round(Context *c,
+   YYLTYPE *locp,
+   HexValue *source,
+   HexValue *position) {
+yyassert(c, locp, source->bit_width <= 32,
+ "fRNDN not implemented for bit widths > 32!");
+
+HexValue src = *source;
+HexValue pos = *position;
+
+HexValue src_width = gen_imm_value(c, locp, src.bit_width, 32);
+HexValue dst_width = gen_imm_value(c, locp, 64, 32);
+HexValue a = gen_extend_op(c, locp, _width, _width, ,
SIGNED);

Are you sure extending is the right thing to do here?


I believe so, the fRNDN definition in macros.h also extends here

  #define fRNDN(A, N) N) == 0) ? (A) : (((fSE32_64(A)) + (1 << ((N) 
- 1))


--
Anton Johansson,
rev.ng Srls.


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

2021-10-18 Thread Anton Johansson via

On 9/7/21 18:08, Taylor Simpson wrote:


+"fNEWREG"|
+"fCAST4s"{ yylval->cast.bit_width = 32;
+   yylval->cast.signedness = SIGNED;
+   return CAST; }

This doesn't look right - is fNEWREG the same as fCAST4s?


We followed the definition of fNEWREG in macros.h where it is given as

  #define fNEWREG(VAL) ((uint32_t) (VAL))


+"fCONSTLL"   { return CONSTLL; }
+"fCONSTULL"  { return CONSTULL; }

These can just be converts.


What is meant by "converts" here?


+"fHINTJR(RsV)"   { /* Emit no token */ }

Put this in the list of IDENTITY above

Same as for fNEWREG. We followed the definition in macros.h as

  #define fHINTJR(TARGET) { /* Not modelled in qemu */ }

where it no-ops.

--
Anton Johansson,
rev.ng Srls.


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

2021-10-18 Thread Anton Johansson via

On 9/7/21 18:09, Taylor Simpson wrote:

+#define fADDSAT64(DST, A, B)\
+__a = fCAST8u(A);   \
+__b = fCAST8u(B);   \
+__sum = __a + __b;  \
+__xor = __a ^ __b;  \
+__mask = fCAST8s(0x8000ULL);\
+if (((__a ^ __b) | ~(__a ^ __sum)) & __mask) {  \
+DST = __sum;\
+} else {\
+DST = ((__sum & __mask) >> 63) + __mask;\
+fSET_OVERFLOW();\
+}

There are a bunch of these with pretty complex semantics.  Wouldn't it be 
easier to recognize them in the parser and call a hand-written helper?

These macro redefinitions are needed to work with the auto type system 
in idef-parser. We can drop these specializations in the upcoming 
patchset where we parse fHIDE declarations.


If we still want to resort to helpers here, it's probably better to 
exclude instructions using fADDSAT64 (and similar) directly, and 
fallback on helpers/overrides for those instructions.


--
Anton Johansson,
rev.ng Srls.


[PATCH v7 10/13] target/hexagon: import parser for idef-parser

2021-12-17 Thread Anton Johansson via
Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
---
 target/hexagon/idef-parser/idef-parser.y| 1064 
 target/hexagon/idef-parser/parser-helpers.c | 2548 +++
 target/hexagon/idef-parser/parser-helpers.h |  379 +++
 target/hexagon/meson.build  |   27 +-
 4 files changed, 4017 insertions(+), 1 deletion(-)
 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..5c3ab3bd07
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,1064 @@
+%{
+/*
+ * Copyright(c) 2019-2021 rev.ng Labs Srl. 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;
+HexSignedness signedness;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token IN INAME VAR
+%token ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS ASL
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE PC NPC LPCFG
+%token CANCEL IDENTITY PART1 BREV_4 BREV_8 ROTL INSBITS SETBITS EXTBITS 
EXTRANGE
+%token CAST4_8U SETOVF FAIL CARRY_FROM_ADD ADDSAT64 LSBNEW
+%token TYPE_SIZE_T TYPE_INT TYPE_SIGNED TYPE_UNSIGNED TYPE_LONG
+
+%token  REG IMM PRED
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement var var_decl var_type
+%type  FAIL
+%type  TYPE_SIGNED TYPE_UNSIGNED TYPE_INT TYPE_LONG TYPE_SIZE_T
+%type  if_stmt IF
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left '('
+%left ','
+%left '='
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left '?' ':'
+%left ANDL
+%left '|'
+%left '^' ANDOR
+%left '&'
+%left EQ NEQ
+%left '<' '>' LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left '-' '+'
+%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
+  {
+  EMIT_SIG(c, ")");
+  EMIT_HEAD(c, "{\n");
+
+  /*
+   * The effective address EA is the only variable passed to
+   * function which needs to be "created".
+   */
+  if (c->inst.EA) {
+  gen_varid_allocate(c, &@1, c->inst.EA, 32, SIGNED);
+  }
+  }
+  code
+  {
+  gen_inst_code(c, &@1);
+  }
+| error /* Recover gracefully after instruction compilation error 
*/
+  {
+  free_instruction(c);
+  }
+;
+
+arguments : '(' ')'
+  | '(' argument_list ')';
+
+argument_list : argument_decl ',' argument_list
+  | argument_decl
+  ;
+
+var : VAR
+  {
+  track_string(c, $1.var.name);
+  $$ = $1;
+  }
+;
+
+/*
+ * Here the integer types are defined from valid combinations of
+ * "signed", "unsigned", "int", and "long" tokens.  The "signed"
+ * and "unsigned" tokens are here assumed to always be placed
+ * first in the type declaration, which is not the case in
+ * normal C. Similarly, "int" is assumed to be placed in the type.
+ */
+type_int : TYPE_INT
+ | 

[PATCH v7 00/13] target/hexagon: introduce idef-parser

2021-12-17 Thread Anton Johansson via
This patchset introduces the idef-parser for target/hexagon.

It's the seventh 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:

* Other than minor changes, tweaks, and cleanup, this patchset includes
  one change to the type system of idef-parser. Variables in the parser
  are no longer automatically typed, but we instead rely on declartions
  found inside `fHIDE(int var;)` macros in the input code.

* These commits build successfully on the CI (including using clang),
  with one notable exception. Presently, the `build-user-hexagon` job
  fails due to not being able to find `flex`. We believe this to be
  caused by `debian-hexagon-cross` not being built by the CI.

  Last patch, 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 a 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.

  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

Anton Johansson (1):
  target/hexagon: import parser for idef-parser

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 flex/bison to docker files
  target/hexagon: import lexer for idef-parser

 .gitlab-ci.d/container-cross.yml  |2 +-
 .gitlab-ci.d/container-template.yml   |4 +-
 .gitlab-ci.d/windows.yml  |2 +
 MAINTAINERS   |   11 +-
 meson_options.txt |3 +
 target/hexagon/README |5 +
 target/hexagon/gen_helper_funcs.py|   16 +-
 target/hexagon/gen_helper_protos.py   |   16 +-
 target/hexagon/gen_idef_parser_funcs.py   |  123 +
 target/hexagon/gen_tcg_funcs.py   |   39 +-
 target/hexagon/genptr.c   |  229 +-
 target/hexagon/genptr.h   |   44 +
 target/hexagon/helper.h   |2 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  722 +
 target/hexagon/idef-parser/idef-parser.h  |  259 ++
 target/hexagon/idef-parser/idef-parser.lex|  571 
 target/hexagon/idef-parser/idef-parser.y  | 1064 +++
 target/hexagon/idef-parser/macros.inc |  140 +
 target/hexagon/idef-parser/parser-helpers.c   | 2548 +
 target/hexagon/idef-parser/parser-helpers.h   |  379 +++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/macros.h   |   11 +-
 target/hexagon/meson.build|  137 +-
 target/hexagon/op_helper.c|   39 +-
 target/hexagon/op_helper.h|   37 +
 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/debian-native.docker |3 +
 .../dockerfiles/debian-riscv64-cross.docker   |3 +
 .../dockerfiles/debian-tricore-cross.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 +-
 

[PATCH v7 01/13] target/hexagon: update MAINTAINERS for idef-parser

2021-12-17 Thread Anton Johansson via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7543eb4d59..f6fbc5f664 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -200,6 +200,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
@@ -207,6 +209,13 @@ 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 
+M: Anton Johansson 
+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
@@ -2788,7 +2797,7 @@ R: Paolo Bonzini 
 R: Bandan Das 
 R: Stefan Hajnoczi 
 R: Thomas Huth 
-R: Darren Kenny  
+R: Darren Kenny 
 R: Qiuhao Li 
 S: Maintained
 F: tests/qtest/fuzz/
-- 
2.33.1




[PATCH v7 13/13] gitlab-ci: do not use qemu-project Docker registry

2021-12-17 Thread Anton Johansson 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 a3b5b90552..07531965da 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.33.1




[PATCH v7 06/13] target/hexagon: expose next PC in DisasContext

2021-12-17 Thread Anton Johansson 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.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 b6f541ecb2..d4d4bcf3b2 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -741,11 +741,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, , false) > 0) {
 HEX_DEBUG_PRINT_PKT();
 gen_start_packet(ctx, );
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, [i], );
 }
 gen_commit_packet(env, ctx, );
-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 fccfb94340..0eb96b9621 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -52,6 +52,7 @@ typedef struct DisasContext {
 bool qreg_is_predicated[NUM_QREGS];
 int qreg_log_idx;
 bool pre_commit;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.33.1




[PATCH v7 12/13] target/hexagon: import additional tests

2021-12-17 Thread Anton Johansson 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 8b07a28166..6f1c0830aa 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
@@ -42,4 +42,32 @@ HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 HEX_TESTS += overflow
 
+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 = 

[PATCH v7 05/13] target/hexagon: introduce new helper functions

2021-12-17 Thread Anton Johansson via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code.
"Helper" can here mean two things, a helper in the QEMU sense added to
`helper.h` and `op_helper.c`, but also helper functions providing a
manual TCG implementation of a certain features.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
Signed-off-by: Anton Johansson 
---
 target/hexagon/genptr.c| 166 +++--
 target/hexagon/genptr.h|  16 +++-
 target/hexagon/helper.h|   2 +
 target/hexagon/macros.h|   9 ++
 target/hexagon/op_helper.c |  10 +++
 5 files changed, 195 insertions(+), 8 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index ae798e921e..44a1ec9ccf 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -31,6 +31,12 @@
 #include "gen_tcg_hvx.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]);
@@ -399,18 +405,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,
@@ -423,8 +430,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,
@@ -437,8 +443,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,
@@ -643,5 +648,152 @@ static void vec_to_qvec(size_t size, intptr_t dstoff, 
intptr_t srcoff)
 tcg_temp_free_i64(mask);
 }
 
+void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[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_tl((1 << (width - 1)) - 1);
+TCGv min_val = tcg_const_tl(-(1 << (width - 1)));
+tcg_gen_smin_tl(dest, source, max_val);
+tcg_gen_smax_tl(dest, dest, min_val);
+tcg_temp_free(max_val);
+tcg_temp_free(min_val);
+}
+
+void gen_sat_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_sat_i32(dest, source, width);
+tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest);
+}
+
+void gen_satu_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_const_tl((1 << width) - 1);
+tcg_gen_movcond_tl(TCG_COND_GTU, dest, source, max_val, max_val, source);
+TCGv zero = tcg_const_tl(0);
+tcg_gen_movcond_tl(TCG_COND_LT, dest, source, zero, zero, dest);
+tcg_temp_free(max_val);
+tcg_temp_free(zero);
+}
+
+void gen_satu_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_satu_i32(dest, source, width);
+tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest);
+}
+
+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 

[PATCH v7 08/13] target/hexagon: import flex/bison to docker files

2021-12-17 Thread Anton Johansson via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
---
 .gitlab-ci.d/windows.yml | 2 ++
 tests/docker/dockerfiles/alpine.docker   | 2 ++
 tests/docker/dockerfiles/centos8.docker  | 2 ++
 tests/docker/dockerfiles/debian-amd64.docker | 2 ++
 tests/docker/dockerfiles/debian-native.docker| 3 +++
 tests/docker/dockerfiles/debian-riscv64-cross.docker | 3 +++
 tests/docker/dockerfiles/debian-tricore-cross.docker | 2 ++
 tests/docker/dockerfiles/debian10.docker | 3 +++
 tests/docker/dockerfiles/fedora-i386-cross.docker| 3 +++
 tests/docker/dockerfiles/fedora-win32-cross.docker   | 3 +++
 tests/docker/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 ++
 16 files changed, 39 insertions(+)

diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml
index 309f7e7fb8..2abfe4e91a 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 7e6997e301..45db55ba55 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 7f135f8e8c..d93bbe3002 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 ed546edcd6..805fd6f981 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 efd55cb6e0..02ccaf98fd 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 594d97982c..f5553afc2e 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 d8df2c6117..9191aafc7f 100644
--- a/tests/docker/dockerfiles/debian-tricore-cross.docker
+++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
@@ -16,9 +16,11 @@ MAINTAINER 

[PATCH v7 09/13] target/hexagon: import lexer for idef-parser

2021-12-17 Thread Anton Johansson via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
---
 target/hexagon/idef-parser/idef-parser.h   | 259 ++
 target/hexagon/idef-parser/idef-parser.lex | 571 +
 target/hexagon/meson.build |   4 +
 3 files changed, 834 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..d361ee7e53
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright(c) 2019-2021 rev.ng Labs Srl. 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 } HexRegType;
+
+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  */
+HexRegType 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 PRED token, identifying a predicate
+ */
+typedef struct HexPred {
+char id;/**< Identifier of the predicate */
+} HexPred;
+
+/**
+ * Semantic record of the SAT token, identifying the saturate operator
+ */
+typedef struct HexSat {
+bool set_overflow;   /**< Set-overflow feature for the sat operator  */
+HexSignedness signedness;/**< Unsigned flag for the saturate operator*/
+} HexSat;
+
+/**
+ * Semantic record of the CAST token, identifying the cast operator
+ */
+typedef struct HexCast {
+int bit_width;/**< Bit width of the cast operator 
*/
+HexSignedness signedness; /**< Unsigned flag for the cast operator
*/
+} HexCast;
+
+/**
+ * Semantic record of the EXTRACT token, identifying the cast operator
+ */
+typedef struct 

[PATCH v7 07/13] target/hexagon: prepare input for the idef-parser

2021-12-17 Thread Anton Johansson 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 
Signed-off-by: Anton Johansson 
---
 target/hexagon/gen_idef_parser_funcs.py | 123 +
 target/hexagon/idef-parser/macros.inc   | 140 
 target/hexagon/idef-parser/prepare  |  24 
 target/hexagon/meson.build  |  16 +++
 4 files changed, 303 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..b35dfcde5c
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2021 rev.ng Labs Srl. 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.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[3], '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
+if ( tag in {'M7_wcmpyrw', 'M7_wcmpyrwc',
+ 'M7_wcmpyiw', 'M7_wcmpyiwc',
+ 'M7_wcmpyrw_rnd', 'M7_wcmpyrwc_rnd',
+ 'M7_wcmpyiw_rnd', 'M7_wcmpyiwc_rnd'} ) :
+continue
+## Skip interleave/deinterleave instructions
+if ( tag in {'S2_interleave', 'S2_deinterleave'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag.startswith('S2_cabacdecbin') ) :
+continue
+if ( tag.startswith('A5_ACS') ) :
+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:
+ 

[PATCH v7 02/13] target/hexagon: import README for idef-parser

2021-12-17 Thread Anton Johansson via
From: Alessandro Di Federico 

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

diff --git a/target/hexagon/README b/target/hexagon/README
index 372e24747c..6cb5affddb 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -27,6 +27,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
@@ -47,6 +51,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..65e6bf4ee5
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,722 @@
+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;} */
+   {
+   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 

[PATCH v7 04/13] target/hexagon: make helper functions non-static

2021-12-17 Thread Anton Johansson 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.c| 59 +-
 target/hexagon/genptr.h| 30 +++
 target/hexagon/op_helper.c | 29 +--
 target/hexagon/op_helper.h | 37 
 4 files changed, 113 insertions(+), 42 deletions(-)
 create mode 100644 target/hexagon/op_helper.h

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 2f73300c90..ae798e921e 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -29,6 +29,13 @@
 #undef QEMU_GENERATE
 #include "gen_tcg.h"
 #include "gen_tcg_hvx.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)
@@ -54,7 +61,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) {
@@ -116,7 +123,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 base_val = tcg_temp_new();
 
@@ -270,7 +277,7 @@ static inline void gen_write_ctrl_reg_pair(DisasContext 
*ctx, int reg_num,
 }
 }
 
-static TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign)
+TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign)
 {
 if (sign) {
 tcg_gen_sextract_tl(result, src, N * 8, 8);
@@ -280,7 +287,7 @@ static TCGv gen_get_byte(TCGv result, int N, TCGv src, bool 
sign)
 return result;
 }
 
-static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign)
+TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign)
 {
 TCGv_i64 res64 = tcg_temp_new_i64();
 if (sign) {
@@ -294,7 +301,7 @@ static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 
src, bool sign)
 return result;
 }
 
-static inline TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign)
+TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign)
 {
 if (sign) {
 tcg_gen_sextract_tl(result, src, N * 16, 16);
@@ -304,12 +311,12 @@ static inline TCGv gen_get_half(TCGv result, int N, TCGv 
src, bool sign)
 return result;
 }
 
-static inline void gen_set_half(int N, TCGv result, TCGv src)
+void gen_set_half(int N, TCGv result, TCGv src)
 {
 tcg_gen_deposit_tl(result, result, src, N * 16, 16);
 }
 
-static inline void gen_set_half_i64(int N, TCGv_i64 result, TCGv src)
+void gen_set_half_i64(int N, TCGv_i64 result, TCGv src)
 {
 TCGv_i64 src64 = tcg_temp_new_i64();
 tcg_gen_extu_i32_i64(src64, src);
@@ -317,7 +324,7 @@ static inline void gen_set_half_i64(int N, TCGv_i64 result, 
TCGv src)
 tcg_temp_free_i64(src64);
 }
 
-static void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
+void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
 {
 TCGv_i64 src64 = tcg_temp_new_i64();
 tcg_gen_extu_i32_i64(src64, src);
@@ -392,57 +399,57 @@ 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, uint32_t slot)
+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);
 tcg_gen_mov_tl(hex_store_val32[slot], src);
 }
 
-static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, uint32_t slot)
+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;
 }
 
-static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
-   DisasContext *ctx, uint32_t slot)
+void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
+ uint32_t slot)
 {
 TCGv tmp = tcg_constant_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
 }
 
-static inline void gen_store2(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,
+  

[PATCH v7 03/13] target/hexagon: make slot number an unsigned

2021-12-17 Thread Anton Johansson via
From: Paolo Montesel 

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

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 4419d30e23..2f73300c90 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -30,7 +30,8 @@
 #include "gen_tcg.h"
 #include "gen_tcg_hvx.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_constant_tl(0);
 TCGv slot_mask = tcg_temp_new();
@@ -62,7 +63,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_constant_tl(0);
@@ -390,7 +392,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);
@@ -398,49 +400,49 @@ 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_constant_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store2(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store4(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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);
@@ -449,7 +451,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_constant_i64(src);
 gen_store8(cpu_env, vaddr, tmp, ctx, slot);
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 19d103cad5..3a64357090 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_temp_new();
 TCGv tmp = tcg_temp_new();
-- 
2.33.1




[PATCH v7 11/13] target/hexagon: call idef-parser functions

2021-12-17 Thread Anton Johansson 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. An option is also added to fully
disable the output of the idef-parser, which is useful for debugging purposes.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 meson_options.txt   |  3 +
 target/hexagon/gen_helper_funcs.py  | 16 -
 target/hexagon/gen_helper_protos.py | 16 -
 target/hexagon/gen_tcg_funcs.py | 39 +++-
 target/hexagon/hex_common.py| 10 
 target/hexagon/meson.build  | 92 +++--
 6 files changed, 142 insertions(+), 34 deletions(-)

diff --git a/meson_options.txt b/meson_options.txt
index 4114bfcaa4..9374a8b838 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -206,3 +206,6 @@ option('fdt', type: 'combo', value: 'auto',
 
 option('selinux', type: 'feature', value: 'auto',
description: 'SELinux support in qemu-nbd')
+
+option('hexagon_idef_parser_enabled', type : 'boolean', value : true,
+   description: 'Whether idef-parser should be used to automatically 
generate TCG code for the Hexagon frontend')
diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index a446c45384..7942ffeb34 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -287,11 +287,23 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+if len(sys.argv) > 6:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -308,6 +320,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 3b4e993fd1..29f4b35b7d 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -136,11 +136,23 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+if len(sys.argv) > 6:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -158,6 +170,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 1fd9de95d5..0ea89d1ed7 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -610,7 +610,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):
+   

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

2022-02-09 Thread Anton Johansson via
This patchset introduces the idef-parser for target/hexagon.

It's the eight 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 Pseudocode
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:

* These commits build successfully on the CI (including using clang),
  with one notable exception. Presently, the `build-user-hexagon` job
  fails due to not being able to find `flex`. We believe this to be
  caused by `debian-hexagon-cross` not being built by the CI.

  As such the `debian-hexagon-cross` container will have to be manually
  rebuilt before merging.

* The eight patch, which introduces flex and bison as new build pre-
  requisites using `libvirt-ci` currently points to a fork, not yet
  merged upstream. This will have to be corrected before the final
  version of the patchset.

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

Anton Johansson (2):
  target/hexagon: import flex/bison to docker files
  target/hexagon: import parser for idef-parser

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

Paolo Montesel (4):
  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

 .gitlab-ci.d/cirrus/freebsd-12.vars   |2 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars   |2 +-
 .gitlab-ci.d/windows.yml  |2 +
 .gitmodules   |3 +-
 MAINTAINERS   |9 +
 meson_options.txt |3 +
 target/hexagon/README |5 +
 target/hexagon/gen_helper_funcs.py|   17 +-
 target/hexagon/gen_helper_protos.py   |   17 +-
 target/hexagon/gen_idef_parser_funcs.py   |  125 +
 target/hexagon/gen_tcg_funcs.py   |   41 +-
 target/hexagon/genptr.c   |  230 +-
 target/hexagon/genptr.h   |   44 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  722 +
 target/hexagon/idef-parser/idef-parser.h  |  254 ++
 target/hexagon/idef-parser/idef-parser.lex|  566 
 target/hexagon/idef-parser/idef-parser.y  | 1039 +++
 target/hexagon/idef-parser/macros.inc |  140 +
 target/hexagon/idef-parser/parser-helpers.c   | 2551 +
 target/hexagon/idef-parser/parser-helpers.h   |  375 +++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/macros.h   |   11 +-
 target/hexagon/meson.build|  138 +-
 target/hexagon/op_helper.c|   29 +-
 target/hexagon/op_helper.h|   37 +
 target/hexagon/translate.c|3 +-
 target/hexagon/translate.h|1 +
 tests/docker/dockerfiles/alpine.docker|5 +-
 tests/docker/dockerfiles/centos8.docker   |7 +-
 tests/docker/dockerfiles/debian-amd64.docker  |2 +
 tests/docker/dockerfiles/debian-native.docker |3 +
 .../dockerfiles/debian-riscv64-cross.docker   |3 +
 .../dockerfiles/debian-tricore-cross.docker   |1 +
 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|5 +-
 tests/docker/dockerfiles/opensuse-leap.docker |7 +-
 tests/docker/dockerfiles/ubuntu1804.docker|7 +-
 tests/docker/dockerfiles/ubuntu2004.docker|7 +-
 tests/lcitool/libvirt-ci  |2 +-
 tests/lcitool/projects/qemu.yml   |2 +
 tests/lcitool/refresh |2 +-
 tests/tcg/hexagon/Makefile.target |   28 +-
 tests/tcg/hexagon/crt.S   |   14 +
 tests/tcg/hexagon/test_abs.S  |   17 +
 tests/tcg/hexagon/test_bitcnt.S   |   40 +
 tests/tcg/hexagon/test_bitsplit.S |   22 +
 tests/tcg/hexagon/test_call.S |   64 +
 tests/tcg/hexagon/test_clobber.S  |   29 +
 tests/tcg/hexagon/test_cmp.S  |   31 +
 tests/tcg/hexagon/test_dotnew.S   |   38 +
 

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

2022-02-09 Thread Anton Johansson 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 
Signed-off-by: Anton Johansson 
---
 target/hexagon/gen_idef_parser_funcs.py | 125 +
 target/hexagon/idef-parser/macros.inc   | 140 
 target/hexagon/idef-parser/prepare  |  24 
 target/hexagon/meson.build  |  17 +++
 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..5a802d08aa
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2021 rev.ng Labs Srl. 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.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[3], '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
+if ( tag in {'M7_wcmpyrw', 'M7_wcmpyrwc',
+ 'M7_wcmpyiw', 'M7_wcmpyiwc',
+ 'M7_wcmpyrw_rnd', 'M7_wcmpyrwc_rnd',
+ 'M7_wcmpyiw_rnd', 'M7_wcmpyiwc_rnd'} ) :
+continue
+## Skip interleave/deinterleave instructions
+if ( tag in {'S2_interleave', 'S2_deinterleave'} ) :
+continue
+## Skip instructions using bit reverse
+if ( tag in {'S2_brev', 'S2_brevp', 'S2_ct0', 'S2_ct1',
+ 'S2_ct0p', 'S2_ct1p', 'A4_tlbmatch'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag == 'S2_cabacdecbin' or tag == 'A5_ACS' ) :
+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 = []
+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:
+

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

2022-02-09 Thread Anton Johansson via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
---
 target/hexagon/idef-parser/idef-parser.h   | 254 +
 target/hexagon/idef-parser/idef-parser.lex | 566 +
 target/hexagon/meson.build |   4 +
 3 files changed, 824 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..106eb3ec98
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,254 @@
+/*
+ *  Copyright(c) 2019-2021 rev.ng Labs Srl. 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 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 } HexRegType;
+
+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   
*/
+HexRegType 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 {
+unsigned 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, used when type is VARIABLE   
*/
+uint64_t value; /**< Immediate value, used when type is VALUE 
*/
+uint64_t index; /**< Index, used when type is QEMU_TMP
*/
+};
+enum ImmUnionTag type;  /**< Type of the immediate
*/
+} HexImm;
+
+/**
+ * Semantic record of the PRED token, identifying a predicate
+ */
+typedef struct HexPred {
+char id;/**< Identifier of the predicate  
*/
+} HexPred;
+
+/**
+ * Semantic record of the SAT token, identifying the saturate operator
+ */
+typedef struct HexSat {
+bool set_overflow;  /**< Should the sat. op. set overflow?
*/
+HexSignedness signedness;   /**< Signedness of the sat. op.   
*/
+} HexSat;
+
+/**
+ * Semantic record of the CAST token, identifying the cast operator
+ */
+typedef struct HexCast {
+unsigned bit_width; /**< Bit width of the cast operator   
*/
+HexSignedness signedness;   /**< Unsigned flag for the cast operator  
*/
+} HexCast;
+
+/**
+ * Semantic record of the EXTRACT 

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

2022-02-09 Thread Anton Johansson 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.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 b6f541ecb2..d4d4bcf3b2 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -741,11 +741,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, , false) > 0) {
 HEX_DEBUG_PRINT_PKT();
 gen_start_packet(ctx, );
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, [i], );
 }
 gen_commit_packet(env, ctx, );
-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 fccfb94340..0eb96b9621 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -52,6 +52,7 @@ typedef struct DisasContext {
 bool qreg_is_predicated[NUM_QREGS];
 int qreg_log_idx;
 bool pre_commit;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.34.1




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

2022-02-09 Thread Anton Johansson via
From: Paolo Montesel 

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

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 4419d30e23..2f73300c90 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -30,7 +30,8 @@
 #include "gen_tcg.h"
 #include "gen_tcg_hvx.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_constant_tl(0);
 TCGv slot_mask = tcg_temp_new();
@@ -62,7 +63,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_constant_tl(0);
@@ -390,7 +392,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);
@@ -398,49 +400,49 @@ 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_constant_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store2(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store4(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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);
@@ -449,7 +451,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_constant_i64(src);
 gen_store8(cpu_env, vaddr, tmp, ctx, slot);
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 19d103cad5..3a64357090 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_temp_new();
 TCGv tmp = tcg_temp_new();
-- 
2.34.1




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

2022-02-09 Thread Anton Johansson via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Richard Henderson 
Reviewed-by: Taylor Simpson 
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9814580975..1195edf040 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -200,6 +200,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
@@ -207,6 +209,13 @@ 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 
+M: Anton Johansson 
+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.34.1




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

2022-02-09 Thread Anton Johansson 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. An option is also added to fully
disable the output of the idef-parser, which is useful for debugging
purposes.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 meson_options.txt   |  3 +
 target/hexagon/gen_helper_funcs.py  | 17 +-
 target/hexagon/gen_helper_protos.py | 17 +-
 target/hexagon/gen_tcg_funcs.py | 41 -
 target/hexagon/hex_common.py| 10 
 target/hexagon/meson.build  | 92 +++--
 6 files changed, 146 insertions(+), 34 deletions(-)

diff --git a/meson_options.txt b/meson_options.txt
index 921967eddb..3d66149356 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -208,3 +208,6 @@ option('fdt', type: 'combo', value: 'auto',
 
 option('selinux', type: 'feature', value: 'auto',
description: 'SELinux support in qemu-nbd')
+
+option('hexagon_idef_parser_enabled', type : 'boolean', value : true,
+   description: 'Whether idef-parser should be used to automatically 
generate TCG code for the Hexagon frontend')
diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index a446c45384..71d611283a 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -287,11 +287,24 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+is_idef_parser_enabled = len(sys.argv) > 6
+if is_idef_parser_enabled:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -308,6 +321,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 3b4e993fd1..74eff457a6 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -136,11 +136,24 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+is_idef_parser_enabled = len(sys.argv) > 6
+if is_idef_parser_enabled:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -158,6 +171,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 1fd9de95d5..4d12e192a7 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -610,7 +610,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":
+

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

2022-02-09 Thread Anton Johansson via
Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
---
 target/hexagon/idef-parser/idef-parser.y| 1039 
 target/hexagon/idef-parser/parser-helpers.c | 2551 +++
 target/hexagon/idef-parser/parser-helpers.h |  375 +++
 target/hexagon/meson.build  |   25 +
 4 files changed, 3990 insertions(+)
 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..b6489be9fb
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,1039 @@
+%{
+/*
+ *  Copyright(c) 2019-2021 rev.ng Labs Srl. 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 .
+ */
+
+#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;
+HexSignedness signedness;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token IN INAME VAR
+%token ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS ASL
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE PC NPC LPCFG
+%token CANCEL IDENTITY PART1 ROTL INSBITS SETBITS EXTBITS EXTRANGE
+%token CAST4_8U SETOVF FAIL CARRY_FROM_ADD ADDSAT64 LSBNEW
+%token TYPE_SIZE_T TYPE_INT TYPE_SIGNED TYPE_UNSIGNED TYPE_LONG
+
+%token  REG IMM PRED
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement var var_decl var_type
+%type  FAIL
+%type  TYPE_SIGNED TYPE_UNSIGNED TYPE_INT TYPE_LONG TYPE_SIZE_T
+%type  if_stmt IF
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left '('
+%left ','
+%left '='
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left '?' ':'
+%left ANDL
+%left '|'
+%left '^' ANDOR
+%left '&'
+%left EQ NEQ
+%left '<' '>' LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left '-' '+'
+%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
+  {
+  EMIT_SIG(c, ")");
+  EMIT_HEAD(c, "{\n");
+  }
+  code
+  {
+  gen_inst_code(c, &@1);
+  }
+| error /* Recover gracefully after instruction compilation error 
*/
+  {
+  free_instruction(c);
+  }
+;
+
+arguments : '(' ')'
+  | '(' argument_list ')';
+
+argument_list : argument_decl ',' argument_list
+  | argument_decl
+  ;
+
+var : VAR
+  {
+  track_string(c, $1.var.name);
+  $$ = $1;
+  }
+;
+
+/*
+ * Here the integer types are defined from valid combinations of
+ * "signed", "unsigned", "int", and "long" tokens.  The "signed"
+ * and "unsigned" tokens are here assumed to always be placed
+ * first in the type declaration, which is not the case in
+ * normal C. Similarly, "int" is assumed to be placed in the type.
+ */
+type_int : TYPE_INT
+ | TYPE_SIGNED
+ | TYPE_SIGNED TYPE_INT;
+type_uint : TYPE_UNSIGNED
+  | TYPE_UNSIGNED TYPE_INT;
+type_long : TYPE_LONG
+  | TYPE_LONG TYPE_INT
+  | TYPE_SIGNED TYPE_LONG
+  | TYPE_SIGNED TYPE_LONG TYPE_INT;
+type_ulong : TYPE_UNSIGNED TYPE_LONG
+   | TYPE_UNSIGNED TYPE_LONG TYPE_INT;
+type_longlong : TYPE_LONG 

[PATCH v8 08/12] target/hexagon: import flex/bison to docker files

2022-02-09 Thread Anton Johansson via
Note: In this version of the patchset `tests/lcitool/libvirt-ci` points
to a fork of libvirt-ci that includes flex/bison. This fork has not been
merged upstream yet, and can be found at

  https://gitlab.com/AntonJohansson/libvirt-ci/-/tree/mapping-flex-bison

This patch will have to be modified to point to the upstreamed version
before pulling.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
---
 .gitlab-ci.d/cirrus/freebsd-12.vars  | 2 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars  | 2 +-
 .gitlab-ci.d/windows.yml | 2 ++
 .gitmodules  | 3 ++-
 tests/docker/dockerfiles/alpine.docker   | 5 -
 tests/docker/dockerfiles/centos8.docker  | 7 ---
 tests/docker/dockerfiles/debian-amd64.docker | 2 ++
 tests/docker/dockerfiles/debian-native.docker| 3 +++
 tests/docker/dockerfiles/debian-riscv64-cross.docker | 3 +++
 tests/docker/dockerfiles/debian-tricore-cross.docker | 1 +
 tests/docker/dockerfiles/debian10.docker | 3 +++
 tests/docker/dockerfiles/fedora-i386-cross.docker| 3 +++
 tests/docker/dockerfiles/fedora-win32-cross.docker   | 3 +++
 tests/docker/dockerfiles/fedora-win64-cross.docker   | 3 +++
 tests/docker/dockerfiles/fedora.docker   | 5 +++--
 tests/docker/dockerfiles/opensuse-leap.docker| 7 ---
 tests/docker/dockerfiles/ubuntu1804.docker   | 7 ---
 tests/docker/dockerfiles/ubuntu2004.docker   | 7 ---
 tests/lcitool/libvirt-ci | 2 +-
 tests/lcitool/projects/qemu.yml  | 2 ++
 tests/lcitool/refresh| 2 +-
 21 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/.gitlab-ci.d/cirrus/freebsd-12.vars 
b/.gitlab-ci.d/cirrus/freebsd-12.vars
index 9c52266811..f2385c1b4a 100644
--- a/.gitlab-ci.d/cirrus/freebsd-12.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-12.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='pkg'
 PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc gettext git glib gmake gnutls gsed 
gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh 
libtasn1 libxml2 llvm lttng-ust lzo2 meson ncurses nettle ninja opencv 
p5-Test-Harness perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip 
py38-sphinx py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio 
sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer 
vte3 zstd'
+PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc gettext git glib gmake gnutls gsed 
gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh 
libtasn1 libxml2 llvm lzo2 meson ncurses nettle ninja opencv p5-Test-Harness 
perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx 
py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 
sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 
zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars 
b/.gitlab-ci.d/cirrus/freebsd-13.vars
index 7b44dba324..43904b65fa 100644
--- a/.gitlab-ci.d/cirrus/freebsd-13.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-13.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='pkg'
 PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc gettext git glib gmake gnutls gsed 
gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh 
libtasn1 libxml2 llvm lttng-ust lzo2 meson ncurses nettle ninja opencv 
p5-Test-Harness perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip 
py38-sphinx py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio 
sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer 
vte3 zstd'
+PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc gettext git glib gmake gnutls gsed 
gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh 
libtasn1 libxml2 llvm lzo2 meson ncurses nettle ninja opencv p5-Test-Harness 
perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx 
py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 
sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 
zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml
index 62dd9ed832..4ae49376cf 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 

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

2022-02-09 Thread Anton Johansson via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code, to
correctly implement instruction semantics. "Helper" functions, in the
context of this patch, refers to functions which provide a manual TCG
implementation of certain features.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
Signed-off-by: Anton Johansson 
---
 target/hexagon/genptr.c | 167 ++--
 target/hexagon/genptr.h |  16 +++-
 target/hexagon/macros.h |   9 +++
 3 files changed, 184 insertions(+), 8 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index ae798e921e..9d0c1fe2df 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -31,6 +31,12 @@
 #include "gen_tcg_hvx.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]);
@@ -399,18 +405,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,
@@ -423,8 +430,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,
@@ -437,8 +443,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,
@@ -643,5 +648,153 @@ static void vec_to_qvec(size_t size, intptr_t dstoff, 
intptr_t srcoff)
 tcg_temp_free_i64(mask);
 }
 
+void gen_set_usr_field(int field, TCGv val)
+{
+/*
+ * Apparently tcg_gen_deposit_i32/64 doesn't OR the input value
+ * with the previously present one, as deposit32/64 in bitops.h
+ * does. We therefore copy the old value to `old_usr` to later
+ * OR with it to replicate this behavior.
+ */
+TCGv_i32 old_usr = tcg_temp_new_i32();
+tcg_gen_mov_i32(old_usr, hex_new_value[HEX_REG_USR]);
+tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR],
+   val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+tcg_gen_or_i32(hex_new_value[HEX_REG_USR],
+   old_usr,
+   hex_new_value[HEX_REG_USR]);
+tcg_temp_free(old_usr);
+}
+
+void gen_set_usr_fieldi(int field, int x)
+{
+TCGv val = tcg_constant_tl(x);
+gen_set_usr_field(field, val);
+}
+
+void gen_write_new_pc(TCGv addr)
+{
+/* If there are multiple branches in a packet, ignore the second one */
+TCGv zero = tcg_constant_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);
+}
+
+void gen_sat_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_constant_tl((1 << (width - 1)) - 1);
+TCGv min_val = tcg_constant_tl(-(1 << (width - 1)));
+tcg_gen_smin_tl(dest, source, max_val);
+tcg_gen_smax_tl(dest, dest, min_val);
+}
+
+void gen_sat_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_sat_i32(dest, source, width);
+tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest);
+}
+
+void gen_satu_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_constant_tl((1 << width) - 1);
+TCGv zero = tcg_constant_tl(0);
+tcg_gen_movcond_tl(TCG_COND_GTU, dest, source, max_val, max_val, source);
+tcg_gen_movcond_tl(TCG_COND_LT, dest, source, zero, zero, dest);
+}
+
+void gen_satu_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_satu_i32(dest, source, width);
+tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest);
+}
+
+void gen_sat_i64(TCGv_i64 dest, TCGv_i64 source, int width)
+{
+

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

2022-02-09 Thread Anton Johansson via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/README |   5 +
 target/hexagon/idef-parser/README.rst | 722 ++
 2 files changed, 727 insertions(+)
 create mode 100644 target/hexagon/idef-parser/README.rst

diff --git a/target/hexagon/README b/target/hexagon/README
index 372e24747c..6cb5affddb 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -27,6 +27,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
@@ -47,6 +51,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..65e6bf4ee5
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,722 @@
+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;} */
+   {
+   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 

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

2022-02-09 Thread Anton Johansson via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
Signed-off-by: Anton Johansson 
---
 tests/tcg/hexagon/Makefile.target  | 28 -
 tests/tcg/hexagon/crt.S| 14 +++
 tests/tcg/hexagon/test_abs.S   | 17 
 tests/tcg/hexagon/test_bitcnt.S| 40 +++
 tests/tcg/hexagon/test_bitsplit.S  | 22 ++
 tests/tcg/hexagon/test_call.S  | 64 ++
 tests/tcg/hexagon/test_clobber.S   | 29 ++
 tests/tcg/hexagon/test_cmp.S   | 31 +++
 tests/tcg/hexagon/test_dotnew.S| 38 ++
 tests/tcg/hexagon/test_ext.S   | 13 ++
 tests/tcg/hexagon/test_fibonacci.S | 30 ++
 tests/tcg/hexagon/test_hl.S| 16 
 tests/tcg/hexagon/test_hwloops.S   | 19 +
 tests/tcg/hexagon/test_jmp.S   | 22 ++
 tests/tcg/hexagon/test_lsr.S   | 36 +
 tests/tcg/hexagon/test_mpyi.S  | 17 
 tests/tcg/hexagon/test_packet.S| 29 ++
 tests/tcg/hexagon/test_reorder.S   | 33 +++
 tests/tcg/hexagon/test_round.S | 29 ++
 tests/tcg/hexagon/test_vavgw.S | 31 +++
 tests/tcg/hexagon/test_vcmpb.S | 30 ++
 tests/tcg/hexagon/test_vcmpw.S | 30 ++
 tests/tcg/hexagon/test_vlsrw.S | 20 ++
 tests/tcg/hexagon/test_vmaxh.S | 35 
 tests/tcg/hexagon/test_vminh.S | 35 
 tests/tcg/hexagon/test_vpmpyh.S| 28 +
 tests/tcg/hexagon/test_vspliceb.S  | 31 +++
 27 files changed, 766 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_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_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_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 8b07a28166..508ab08065 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
@@ -42,4 +42,30 @@ HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 HEX_TESTS += overflow
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_call
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+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_packet
+HEX_TESTS += test_reorder
+HEX_TESTS += test_round
+HEX_TESTS += test_vavgw
+HEX_TESTS += test_vcmpb
+HEX_TESTS += test_vcmpw
+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..f9e6bc80f7
--- /dev/null
+++ b/tests/tcg/hexagon/crt.S
@@ -0,0 +1,14 @@
+#define SYS_exit_group 94
+
+.text
+.globl pass
+pass:
+r0 = #0
+r6 = #SYS_exit_group
+trap0(#1)
+
+.globl fail
+fail:
+r0 = #1
+r6 = #SYS_exit_group
+trap0(#1)
diff --git a/tests/tcg/hexagon/test_abs.S b/tests/tcg/hexagon/test_abs.S
new file mode 100644
index 00..d68aea6f64
--- /dev/null
+++ b/tests/tcg/hexagon/test_abs.S
@@ -0,0 +1,17 @@
+/* Purpose: test example, verify the soundness of the abs operation */
+
+.text
+.globl _start
+
+_start:
+{
+r1 = #-2
+r2 = #2
+}
+{
+r3 = abs(r1)
+}
+{
+p0 = cmp.eq(r3, r2); if (p0.new) jump:t 

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

2022-02-09 Thread Anton Johansson 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.c| 59 +-
 target/hexagon/genptr.h| 30 +++
 target/hexagon/op_helper.c | 29 +--
 target/hexagon/op_helper.h | 37 
 4 files changed, 113 insertions(+), 42 deletions(-)
 create mode 100644 target/hexagon/op_helper.h

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 2f73300c90..ae798e921e 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -29,6 +29,13 @@
 #undef QEMU_GENERATE
 #include "gen_tcg.h"
 #include "gen_tcg_hvx.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)
@@ -54,7 +61,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) {
@@ -116,7 +123,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 base_val = tcg_temp_new();
 
@@ -270,7 +277,7 @@ static inline void gen_write_ctrl_reg_pair(DisasContext 
*ctx, int reg_num,
 }
 }
 
-static TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign)
+TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign)
 {
 if (sign) {
 tcg_gen_sextract_tl(result, src, N * 8, 8);
@@ -280,7 +287,7 @@ static TCGv gen_get_byte(TCGv result, int N, TCGv src, bool 
sign)
 return result;
 }
 
-static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign)
+TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign)
 {
 TCGv_i64 res64 = tcg_temp_new_i64();
 if (sign) {
@@ -294,7 +301,7 @@ static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 
src, bool sign)
 return result;
 }
 
-static inline TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign)
+TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign)
 {
 if (sign) {
 tcg_gen_sextract_tl(result, src, N * 16, 16);
@@ -304,12 +311,12 @@ static inline TCGv gen_get_half(TCGv result, int N, TCGv 
src, bool sign)
 return result;
 }
 
-static inline void gen_set_half(int N, TCGv result, TCGv src)
+void gen_set_half(int N, TCGv result, TCGv src)
 {
 tcg_gen_deposit_tl(result, result, src, N * 16, 16);
 }
 
-static inline void gen_set_half_i64(int N, TCGv_i64 result, TCGv src)
+void gen_set_half_i64(int N, TCGv_i64 result, TCGv src)
 {
 TCGv_i64 src64 = tcg_temp_new_i64();
 tcg_gen_extu_i32_i64(src64, src);
@@ -317,7 +324,7 @@ static inline void gen_set_half_i64(int N, TCGv_i64 result, 
TCGv src)
 tcg_temp_free_i64(src64);
 }
 
-static void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
+void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
 {
 TCGv_i64 src64 = tcg_temp_new_i64();
 tcg_gen_extu_i32_i64(src64, src);
@@ -392,57 +399,57 @@ 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, uint32_t slot)
+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);
 tcg_gen_mov_tl(hex_store_val32[slot], src);
 }
 
-static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, uint32_t slot)
+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;
 }
 
-static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
-   DisasContext *ctx, uint32_t slot)
+void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
+ uint32_t slot)
 {
 TCGv tmp = tcg_constant_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
 }
 
-static inline void gen_store2(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,
+  

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

2022-04-12 Thread Anton Johansson via
Very nice catch, this is the bug that plagued us a few weeks ago when 
rebasing,
it has since been fixed. Actually the `gen_set_overflow` fucntion has 
been removed

completely as it was only called when we handled `asl/asr_r_r_sat`.

Current way we handle overflow:

Overflow is now only set by saturates, this assumption holds for the 
instructions
we parse in phase 1. In the parser, all saturates call `gen_rvalue_sat` 
which emits
a call to `gen_set_usr_field_if` in `genptr.c` to set USR_OVF only if 
the value is

non-zero. It does this via OR'ing with the previous value.

See here 
 
for `gen_rvalue_sat`
and here 
 
for `gen_set_usr_field_if`





-Original Message-
From: Anton Johansson
Sent: Wednesday, February 9, 2022 11:03 AM
To:qemu-devel@nongnu.org
Cc:a...@rev.ng; Taylor Simpson; Brian Cain
; Michael Lambert;
bab...@rev.ng;ni...@rev.ng;richard.hender...@linaro.org
Subject: [PATCH v8 10/12] target/hexagon: import parser for idef-parser

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



diff --git a/target/hexagon/idef-parser/parser-helpers.c
b/target/hexagon/idef-parser/parser-helpers.c
new file mode 100644




+void gen_set_overflow(Context *c, YYLTYPE *locp, HexValue *value)
+{
+HexValue value_m = *value;
+
+if (is_inside_ternary(c)) {
+/* Inside ternary operator, need to take care of the side-effect */
+HexValue cond = get_ternary_cond(c, locp);
+HexValue zero = gen_constant(c, locp, "0", cond.bit_width,
UNSIGNED);
+bool is_64bit = cond.bit_width == 64;
+unsigned bit_width = cond.bit_width;
+value_m = rvalue_materialize(c, locp, _m);
+if (is_64bit) {
+value_m = gen_rvalue_extend(c, locp, _m);
+}
+OUT(c, locp, "tcg_gen_movcond_i", _width,
+ "(TCG_COND_NE, ", _m, ", ", );
+OUT(c, locp, ", ", , ", ", _m, ", ", , ");\n");

You shouldn't write zero when the condition is false - you should do nothing.  
Try a test where OVF is already set.  You can't overwrite the bit with zero 
when the current instruction doesn't overflow.




+if (is_64bit) {
+value_m = gen_rvalue_truncate(c, locp, _m);
+}
+gen_rvalue_free(c, locp, );
+}
+
+OUT(c, locp, "SET_USR_FIELD(USR_OVF, ", _m, ");\n");
+gen_rvalue_free(c, locp, _m);
+}

Re: [PATCH 00/11] accel/tcg: Make more files target agnostic (& exec/ housekeeping)

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> While reviewing Anton/Richard series [*] it was a bit hard
> for me to figure out which headers are target specific and
> "taint" the source which include them, in that we can not
> compile them once for all targets.
> 
> My understanding is -all.h suffix is a target specific header,
> and -common.c is a target agnostic file. I tried to consolidate
> a bit renaming some files with the -target.c suffix (I'd like
> to rename -all.h -> .target.h for parity / clarity, but that
> is too much code churn at this point).

Nice, very much appreciated, I've also been struggling a bit with 
keeping track of especially target-agnostic/dependent headers.

-- 
Anton Johansson
rev.ng Labs Srl.



Re: [PATCH 02/11] exec: Move cpu_loop_foo() target agnostic functions to 'cpu-common.h'

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> While these functions are not TCG specific, they are not target
> specific. Move them to "exec/cpu-common.h" so their callers don't
> have to be tainted as target specific.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  include/exec/cpu-common.h | 32 
>  include/exec/exec-all.h   | 30 --
>  2 files changed, 32 insertions(+), 30 deletions(-)
> 
> diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
> index 360b8298a4..605b160a7e 100644
> --- a/include/exec/cpu-common.h
> +++ b/include/exec/cpu-common.h
> @@ -173,4 +173,36 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
>  /* vl.c */
>  void list_cpus(void);
>  
> +#ifdef CONFIG_TCG
> +/**
> + * cpu_unwind_state_data:
> + * @cpu: the cpu context
> + * @host_pc: the host pc within the translation
> + * @data: output data
> + *
> + * Attempt to load the the unwind state for a host pc occurring in
> + * translated code.  If @host_pc is not in translated code, the
> + * function returns false; otherwise @data is loaded.
> + * This is the same unwind info as given to restore_state_to_opc.
> + */
> +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
> +
> +/**
> + * cpu_restore_state:
> + * @cpu: the cpu context
> + * @host_pc: the host pc within the translation
> + * @return: true if state was restored, false otherwise
> + *
> + * Attempt to restore the state for a fault occurring in translated
> + * code. If @host_pc is not in translated code no state is
> + * restored and the function returns false.
> + */
> +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc);
> +
> +G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
> +G_NORETURN void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc);
> +#endif /* CONFIG_TCG */
> +G_NORETURN void cpu_loop_exit(CPUState *cpu);
> +G_NORETURN void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc);
> +
>  #endif /* CPU_COMMON_H */
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 2e4d337805..ee90ef122b 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -27,36 +27,6 @@
>  #include "exec/translation-block.h"
>  #include "qemu/clang-tsa.h"
>  
> -/**
> - * cpu_unwind_state_data:
> - * @cpu: the cpu context
> - * @host_pc: the host pc within the translation
> - * @data: output data
> - *
> - * Attempt to load the the unwind state for a host pc occurring in
> - * translated code.  If @host_pc is not in translated code, the
> - * function returns false; otherwise @data is loaded.
> - * This is the same unwind info as given to restore_state_to_opc.
> - */
> -bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
> -
> -/**
> - * cpu_restore_state:
> - * @cpu: the cpu context
> - * @host_pc: the host pc within the translation
> - * @return: true if state was restored, false otherwise
> - *
> - * Attempt to restore the state for a fault occurring in translated
> - * code. If @host_pc is not in translated code no state is
> - * restored and the function returns false.
> - */
> -bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc);
> -
> -G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
> -G_NORETURN void cpu_loop_exit(CPUState *cpu);
> -G_NORETURN void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc);
> -G_NORETURN void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc);
> -
>  /**
>   * cpu_loop_exit_requested:
>   * @cpu: The CPU state to be tested
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 03/11] accel/tcg: Restrict dump_exec_info() declaration

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> In commit 00c9a5c2c3 ("accel/tcg: Restrict 'qapi-commands-machine.h'
> to system emulation") we moved the definition to accel/tcg/ which is
> where this function is called. No need to expose it outside.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  accel/tcg/internal.h   | 2 ++
>  include/exec/cpu-all.h | 5 -
>  2 files changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
> index e8cbbde581..cd6b9eb7f0 100644
> --- a/accel/tcg/internal.h
> +++ b/accel/tcg/internal.h
> @@ -102,6 +102,8 @@ static inline bool cpu_in_serial_context(CPUState *cs)
>  extern int64_t max_delay;
>  extern int64_t max_advance;
>  
> +void dump_exec_info(GString *buf);
> +
>  extern bool one_insn_per_tb;
>  
>  /**
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 71efc2d404..221ada2b6d 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -406,11 +406,6 @@ static inline bool tlb_hit(uint64_t tlb_addr, vaddr addr)
>  return tlb_hit_page(tlb_addr, addr & TARGET_PAGE_MASK);
>  }
>  
> -#ifdef CONFIG_TCG
> -/* accel/tcg/translate-all.c */
> -void dump_exec_info(GString *buf);
> -#endif /* CONFIG_TCG */
> -
>  #endif /* !CONFIG_USER_ONLY */
>  
>  /* accel/tcg/cpu-exec.c */
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 06/11] exec: Rename cpu.c -> cpu-target.c

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> We have exec/cpu code split in 2 files for target agnostic
> ("common") and specific. Rename 'cpu.c' which is target
> specific using the '-target' suffix. Update MAINTAINERS.
> Remove the 's from 'cpus-common.c' to match the API cpu_foo()
> functions.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  MAINTAINERS   | 4 ++--
>  meson.build   | 4 ++--
>  cpus-common.c => cpu-common.c | 0
>  cpu.c => cpu-target.c | 0
>  4 files changed, 4 insertions(+), 4 deletions(-)
>  rename cpus-common.c => cpu-common.c (100%)
>  rename cpu.c => cpu-target.c (100%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 00562f924f..12261d8eaf 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -139,7 +139,8 @@ R: Paolo Bonzini 
>  S: Maintained
>  F: softmmu/cpus.c
>  F: softmmu/watchpoint.c
> -F: cpus-common.c
> +F: cpu-common.c
> +F: cpu-target.c
>  F: page-vary.c
>  F: page-vary-common.c
>  F: accel/tcg/
> @@ -1772,7 +1773,6 @@ M: Marcel Apfelbaum 
>  R: Philippe Mathieu-Daudé 
>  R: Yanan Wang 
>  S: Supported
> -F: cpu.c
Was the maintainer switch intentional?

Either way,
Reviewed-by: Anton Johansson 



Re: [PATCH 09/11] accel/tcg: Make monitor.c a target-agnostic unit

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> Move target-agnostic declarations from "internal-target.h"
> to a new "internal-common.h" header.
> monitor.c now don't include target specific headers and can
> be compiled once in system_ss[].
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  accel/tcg/internal-common.h | 17 +
>  accel/tcg/internal-target.h |  5 -
>  accel/tcg/cpu-exec.c|  1 +
>  accel/tcg/monitor.c |  2 +-
>  accel/tcg/translate-all.c   |  1 +
>  accel/tcg/meson.build   |  3 +++
>  6 files changed, 23 insertions(+), 6 deletions(-)
>  create mode 100644 accel/tcg/internal-common.h
> 
> diff --git a/accel/tcg/internal-common.h b/accel/tcg/internal-common.h
> new file mode 100644
> index 00..5d5247442e
> --- /dev/null
> +++ b/accel/tcg/internal-common.h
> @@ -0,0 +1,17 @@
> +/*
> + * Internal execution defines for qemu (target agnostic)
> + *
> + *  Copyright (c) 2003 Fabrice Bellard
> + *
> + * SPDX-License-Identifier: LGPL-2.1-or-later
> + */
> +
> +#ifndef ACCEL_TCG_INTERNAL_COMMON_H
> +#define ACCEL_TCG_INTERNAL_COMMON_H
> +
> +extern int64_t max_delay;
> +extern int64_t max_advance;
> +
> +void dump_exec_info(GString *buf);
> +
> +#endif
> diff --git a/accel/tcg/internal-target.h b/accel/tcg/internal-target.h
> index 4ce3b29056..f9eec1ce28 100644
> --- a/accel/tcg/internal-target.h
> +++ b/accel/tcg/internal-target.h
> @@ -99,11 +99,6 @@ static inline bool cpu_in_serial_context(CPUState *cs)
>  return !(cs->tcg_cflags & CF_PARALLEL) || cpu_in_exclusive_context(cs);
>  }
>  
> -extern int64_t max_delay;
> -extern int64_t max_advance;
> -
> -void dump_exec_info(GString *buf);
> -
>  extern bool one_insn_per_tb;
>  
>  /**
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index f5625e047a..95dd8a30cb 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -42,6 +42,7 @@
>  #include "tb-jmp-cache.h"
>  #include "tb-hash.h"
>  #include "tb-context.h"
> +#include "internal-common.h"
>  #include "internal-target.h"
>  
>  /* -icount align implementation. */
> diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
> index 30724fdb98..caf1189e0b 100644
> --- a/accel/tcg/monitor.c
> +++ b/accel/tcg/monitor.c
> @@ -16,7 +16,7 @@
>  #include "sysemu/cpu-timers.h"
>  #include "sysemu/tcg.h"
>  #include "tcg/tcg.h"
> -#include "internal-target.h"
> +#include "internal-common.h"
>  
>  
>  static void dump_drift_info(GString *buf)
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index 6c09b7f50d..8cb6ad3511 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -61,6 +61,7 @@
>  #include "tb-jmp-cache.h"
>  #include "tb-hash.h"
>  #include "tb-context.h"
> +#include "internal-common.h"
>  #include "internal-target.h"
>  #include "perf.h"
>  #include "tcg/insn-start-words.h"
> diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
> index 8ace783707..0fb03bd7d3 100644
> --- a/accel/tcg/meson.build
> +++ b/accel/tcg/meson.build
> @@ -20,6 +20,9 @@ specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
>  
>  specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files(
>'cputlb.c',
> +))
> +
> +system_ss.add(when: ['CONFIG_TCG'], if_true: files(
>'monitor.c',
>  ))
>  
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 11/11] accel/tcg: Make cpu-exec-common.c a target agnostic unit

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> cpu_in_serial_context() is not target specific,
> move it declaration to "internal-common.h" (which
> we include in the 4 source files modified).
> 
> Remove the unused "exec/exec-all.h" header from
> cpu-exec-common.c.  There is no more target specific
> code in this file: make it target agnostic.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  accel/tcg/internal-common.h | 11 +++
>  accel/tcg/internal-target.h |  9 -
>  accel/tcg/cpu-exec-common.c |  3 +--
>  accel/tcg/cputlb.c  |  1 +
>  accel/tcg/tb-maint.c|  1 +
>  accel/tcg/user-exec.c   |  1 +
>  accel/tcg/meson.build   |  4 +++-
>  7 files changed, 18 insertions(+), 12 deletions(-)
> 
> diff --git a/accel/tcg/internal-common.h b/accel/tcg/internal-common.h
> index 5d5247442e..3b2277e6e9 100644
> --- a/accel/tcg/internal-common.h
> +++ b/accel/tcg/internal-common.h
> @@ -9,9 +9,20 @@
>  #ifndef ACCEL_TCG_INTERNAL_COMMON_H
>  #define ACCEL_TCG_INTERNAL_COMMON_H
>  
> +#include "exec/translation-block.h"
> +
>  extern int64_t max_delay;
>  extern int64_t max_advance;
>  
>  void dump_exec_info(GString *buf);
>  
> +/*
> + * Return true if CS is not running in parallel with other cpus, either
> + * because there are no other cpus or we are within an exclusive context.
> + */
> +static inline bool cpu_in_serial_context(CPUState *cs)
> +{
> +return !(cs->tcg_cflags & CF_PARALLEL) || cpu_in_exclusive_context(cs);
> +}
> +
>  #endif
> diff --git a/accel/tcg/internal-target.h b/accel/tcg/internal-target.h
> index f9eec1ce28..932bbe4b63 100644
> --- a/accel/tcg/internal-target.h
> +++ b/accel/tcg/internal-target.h
> @@ -90,15 +90,6 @@ static inline vaddr log_pc(CPUState *cpu, const 
> TranslationBlock *tb)
>  }
>  }
>  
> -/*
> - * Return true if CS is not running in parallel with other cpus, either
> - * because there are no other cpus or we are within an exclusive context.
> - */
> -static inline bool cpu_in_serial_context(CPUState *cs)
> -{
> -return !(cs->tcg_cflags & CF_PARALLEL) || cpu_in_exclusive_context(cs);
> -}
> -
>  extern bool one_insn_per_tb;
>  
>  /**
> diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
> index 55980417b4..b6cc387482 100644
> --- a/accel/tcg/cpu-exec-common.c
> +++ b/accel/tcg/cpu-exec-common.c
> @@ -20,9 +20,8 @@
>  #include "qemu/osdep.h"
>  #include "sysemu/cpus.h"
>  #include "sysemu/tcg.h"
> -#include "exec/exec-all.h"
>  #include "qemu/plugin.h"
> -#include "internal-target.h"
> +#include "internal-common.h"
>  
>  bool tcg_allowed;
>  
> diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
> index a912d746a9..400d9ee0d0 100644
> --- a/accel/tcg/cputlb.c
> +++ b/accel/tcg/cputlb.c
> @@ -35,6 +35,7 @@
>  #include "exec/translate-all.h"
>  #include "trace.h"
>  #include "tb-hash.h"
> +#include "internal-common.h"
>  #include "internal-target.h"
>  #ifdef CONFIG_PLUGIN
>  #include "qemu/plugin-memory.h"
> diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
> index 85cf51445d..b194f8f065 100644
> --- a/accel/tcg/tb-maint.c
> +++ b/accel/tcg/tb-maint.c
> @@ -29,6 +29,7 @@
>  #include "tcg/tcg.h"
>  #include "tb-hash.h"
>  #include "tb-context.h"
> +#include "internal-common.h"
>  #include "internal-target.h"
>  
>  
> diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
> index f925dd0305..5bf2761bf4 100644
> --- a/accel/tcg/user-exec.c
> +++ b/accel/tcg/user-exec.c
> @@ -29,6 +29,7 @@
>  #include "qemu/atomic128.h"
>  #include "trace/trace-root.h"
>  #include "tcg/tcg-ldst.h"
> +#include "internal-common.h"
>  #include "internal-target.h"
>  
>  __thread uintptr_t helper_retaddr;
> diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
> index 4633a34d28..8783edd06e 100644
> --- a/accel/tcg/meson.build
> +++ b/accel/tcg/meson.build
> @@ -1,7 +1,9 @@
>  tcg_ss = ss.source_set()
> +common_ss.add(when: 'CONFIG_TCG', if_true: files(
> +  'cpu-exec-common.c',
> +))
>  tcg_ss.add(files(
>'tcg-all.c',
> -  'cpu-exec-common.c',
>'cpu-exec.c',
>'tb-maint.c',
>'tcg-runtime-gvec.c',
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 08/11] accel/tcg: Rename target-specific 'internal.h' -> 'internal-target.h'

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> accel/tcg/internal.h contains target specific declarations.
> Unit files including it become "target tainted": they can not
> be compiled as target agnostic. Rename using the '-target'
> suffix to make this explicit.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  accel/tcg/{internal.h => internal-target.h} | 6 +++---
>  accel/tcg/cpu-exec-common.c | 2 +-
>  accel/tcg/cpu-exec.c| 2 +-
>  accel/tcg/cputlb.c  | 2 +-
>  accel/tcg/monitor.c | 2 +-
>  accel/tcg/tb-maint.c| 2 +-
>  accel/tcg/tcg-all.c | 2 +-
>  accel/tcg/translate-all.c   | 2 +-
>  accel/tcg/translator.c  | 2 +-
>  accel/tcg/user-exec.c   | 2 +-
>  10 files changed, 12 insertions(+), 12 deletions(-)
>  rename accel/tcg/{internal.h => internal-target.h} (96%)
> 
> diff --git a/accel/tcg/internal.h b/accel/tcg/internal-target.h
> similarity index 96%
> rename from accel/tcg/internal.h
> rename to accel/tcg/internal-target.h
> index cd6b9eb7f0..4ce3b29056 100644
> --- a/accel/tcg/internal.h
> +++ b/accel/tcg/internal-target.h
> @@ -1,13 +1,13 @@
>  /*
> - * Internal execution defines for qemu
> + * Internal execution defines for qemu (target specific)
>   *
>   *  Copyright (c) 2003 Fabrice Bellard
>   *
>   * SPDX-License-Identifier: LGPL-2.1-or-later
>   */
>  
> -#ifndef ACCEL_TCG_INTERNAL_H
> -#define ACCEL_TCG_INTERNAL_H
> +#ifndef ACCEL_TCG_INTERNAL_TARGET_H
> +#define ACCEL_TCG_INTERNAL_TARGET_H
>  
>  #include "exec/exec-all.h"
>  #include "exec/translate-all.h"
> diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
> index 8ac2af4d0c..55980417b4 100644
> --- a/accel/tcg/cpu-exec-common.c
> +++ b/accel/tcg/cpu-exec-common.c
> @@ -22,7 +22,7 @@
>  #include "sysemu/tcg.h"
>  #include "exec/exec-all.h"
>  #include "qemu/plugin.h"
> -#include "internal.h"
> +#include "internal-target.h"
>  
>  bool tcg_allowed;
>  
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index 0e7eeef001..f5625e047a 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -42,7 +42,7 @@
>  #include "tb-jmp-cache.h"
>  #include "tb-hash.h"
>  #include "tb-context.h"
> -#include "internal.h"
> +#include "internal-target.h"
>  
>  /* -icount align implementation. */
>  
> diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
> index 31e34700ea..a912d746a9 100644
> --- a/accel/tcg/cputlb.c
> +++ b/accel/tcg/cputlb.c
> @@ -35,7 +35,7 @@
>  #include "exec/translate-all.h"
>  #include "trace.h"
>  #include "tb-hash.h"
> -#include "internal.h"
> +#include "internal-target.h"
>  #ifdef CONFIG_PLUGIN
>  #include "qemu/plugin-memory.h"
>  #endif
> diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
> index d48de23999..30724fdb98 100644
> --- a/accel/tcg/monitor.c
> +++ b/accel/tcg/monitor.c
> @@ -16,7 +16,7 @@
>  #include "sysemu/cpu-timers.h"
>  #include "sysemu/tcg.h"
>  #include "tcg/tcg.h"
> -#include "internal.h"
> +#include "internal-target.h"
>  
>  
>  static void dump_drift_info(GString *buf)
> diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
> index 32ae8af61c..85cf51445d 100644
> --- a/accel/tcg/tb-maint.c
> +++ b/accel/tcg/tb-maint.c
> @@ -29,7 +29,7 @@
>  #include "tcg/tcg.h"
>  #include "tb-hash.h"
>  #include "tb-context.h"
> -#include "internal.h"
> +#include "internal-target.h"
>  
>  
>  /* List iterators for lists of tagged pointers in TranslationBlock. */
> diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
> index 03dfd67e9e..b32e0b80ec 100644
> --- a/accel/tcg/tcg-all.c
> +++ b/accel/tcg/tcg-all.c
> @@ -38,7 +38,7 @@
>  #if !defined(CONFIG_USER_ONLY)
>  #include "hw/boards.h"
>  #endif
> -#include "internal.h"
> +#include "internal-target.h"
>  
>  struct TCGState {
>  AccelState parent_obj;
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index 83e07b830f..6c09b7f50d 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -61,7 +61,7 @@
>  #include "tb-jmp-cache.h"
>  #include "tb-hash.h"
>  #include "tb-context.h"
> -#include "internal.h"
> +#include "internal-target.h"
>  #include "perf.h"
>  #include "tcg/insn-start-words.h"
>  
> diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
> index d9fcb4cbe8..65219b52eb 100644
> --- a/accel/tcg/translator.c
> +++ b/accel/tcg/translator.c
> @@ -14,7 +14,7 @@
>  #include "exec/translator.h"
>  #include "exec/plugin-gen.h"
>  #include "tcg/tcg-op-common.h"
> -#include "internal.h"
> +#include "internal-target.h"
>  
>  static void gen_io_start(void)
>  {
> diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
> index 17f9aff0cf..f925dd0305 100644
> --- a/accel/tcg/user-exec.c
> +++ b/accel/tcg/user-exec.c
> @@ -29,7 +29,7 @@
>  #include "qemu/atomic128.h"
>  #include "trace/trace-root.h"
>  #include "tcg/tcg-ldst.h"
> -#include "internal.h"
> +#include 

Re: [PATCH 05/11] accel: Rename accel-common.c -> accel-target.c

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> We use the '-common.c' suffix for target agnostic units.
> This file is target specific, rename it using the '-target'
> suffix.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  accel/{accel-common.c => accel-target.c} | 0
>  accel/meson.build| 2 +-
>  2 files changed, 1 insertion(+), 1 deletion(-)
>  rename accel/{accel-common.c => accel-target.c} (100%)
> 
> diff --git a/accel/accel-common.c b/accel/accel-target.c
> similarity index 100%
> rename from accel/accel-common.c
> rename to accel/accel-target.c
> diff --git a/accel/meson.build b/accel/meson.build
> index 76f3cbc530..fda3157a6e 100644
> --- a/accel/meson.build
> +++ b/accel/meson.build
> @@ -1,4 +1,4 @@
> -specific_ss.add(files('accel-common.c'))
> +specific_ss.add(files('accel-target.c'))
>  system_ss.add(files('accel-softmmu.c', 'accel-blocker.c'))
>  user_ss.add(files('accel-user.c'))
>  
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 01/11] exec: Make EXCP_FOO definitions target agnostic

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> The EXCP_* definitions don't need to be target specific,
> move them to "exec/cpu-common.h".
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  include/exec/cpu-all.h| 7 ---
>  include/exec/cpu-common.h | 7 +++
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 3b1cec390b..71efc2d404 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -26,13 +26,6 @@
>  #include "hw/core/cpu.h"
>  #include "qemu/rcu.h"
>  
> -#define EXCP_INTERRUPT  0x1 /* async interruption */
> -#define EXCP_HLT0x10001 /* hlt instruction reached */
> -#define EXCP_DEBUG  0x10002 /* cpu stopped after a breakpoint or 
> singlestep */
> -#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external 
> event) */
> -#define EXCP_YIELD  0x10004 /* cpu wants to yield timeslice to another */
> -#define EXCP_ATOMIC 0x10005 /* stop-the-world and emulate atomic */
> -
>  /* some important defines:
>   *
>   * HOST_BIG_ENDIAN : whether the host cpu is big endian and
> diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
> index 41788c0bdd..360b8298a4 100644
> --- a/include/exec/cpu-common.h
> +++ b/include/exec/cpu-common.h
> @@ -7,6 +7,13 @@
>  #include "exec/hwaddr.h"
>  #endif
>  
> +#define EXCP_INTERRUPT  0x1 /* async interruption */
> +#define EXCP_HLT0x10001 /* hlt instruction reached */
> +#define EXCP_DEBUG  0x10002 /* cpu stopped after a breakpoint or 
> singlestep */
> +#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external 
> event) */
> +#define EXCP_YIELD  0x10004 /* cpu wants to yield timeslice to another */
> +#define EXCP_ATOMIC 0x10005 /* stop-the-world and emulate atomic */
> +
>  /**
>   * vaddr:
>   * Type wide enough to contain any #target_ulong virtual address.
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 04/11] accel: Make accel-blocker.o target agnostic

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> accel-blocker.c is not target specific, move it to system_ss[].
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  accel/meson.build | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/accel/meson.build b/accel/meson.build
> index 638a9a03ba..76f3cbc530 100644
> --- a/accel/meson.build
> +++ b/accel/meson.build
> @@ -1,5 +1,5 @@
> -specific_ss.add(files('accel-common.c', 'accel-blocker.c'))
> -system_ss.add(files('accel-softmmu.c'))
> +specific_ss.add(files('accel-common.c'))
> +system_ss.add(files('accel-softmmu.c', 'accel-blocker.c'))
>  user_ss.add(files('accel-user.c'))
>  
>  subdir('tcg')
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 07/11] exec: Rename target specific page-vary.c -> page-vary-target.c

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> This matches the target agnostic 'page-vary-common.c' counterpart.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  MAINTAINERS   | 2 +-
>  meson.build   | 2 +-
>  page-vary.c => page-vary-target.c | 0
>  3 files changed, 2 insertions(+), 2 deletions(-)
>  rename page-vary.c => page-vary-target.c (100%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 12261d8eaf..ff436dbf21 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -141,7 +141,7 @@ F: softmmu/cpus.c
>  F: softmmu/watchpoint.c
>  F: cpu-common.c
>  F: cpu-target.c
> -F: page-vary.c
> +F: page-vary-target.c
>  F: page-vary-common.c
>  F: accel/tcg/
>  F: accel/stubs/tcg-stub.c
> diff --git a/meson.build b/meson.build
> index 3e86a6cebf..3282f888a3 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -3439,7 +3439,7 @@ if get_option('b_lto')
>pagevary = declare_dependency(link_with: pagevary)
>  endif
>  common_ss.add(pagevary)
> -specific_ss.add(files('page-vary.c'))
> +specific_ss.add(files('page-vary-target.c'))
>  
>  subdir('backends')
>  subdir('disas')
> diff --git a/page-vary.c b/page-vary-target.c
> similarity index 100%
> rename from page-vary.c
> rename to page-vary-target.c
> -- 
> 2.41.0
> 
Reviewed-by: Anton Johansson 



Re: [PATCH 10/11] accel/tcg: Make icount.o a target agnostic unit

2023-09-15 Thread Anton Johansson via
On 14/09/23, Philippe Mathieu-Daudé wrote:
> Remove the unused "exec/exec-all.h" header. There is
> no more target specific code in it: make it target
> agnostic (rename using the '-common' suffix). Since
> it is TCG specific, move it to accel/tcg, updating
> MAINTAINERS.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  MAINTAINERS   | 1 -
>  softmmu/icount.c => accel/tcg/icount-common.c | 3 +--
>  accel/tcg/meson.build | 1 +
>  softmmu/meson.build   | 4 
>  4 files changed, 2 insertions(+), 7 deletions(-)
>  rename softmmu/icount.c => accel/tcg/icount-common.c (99%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ff436dbf21..047d143b9d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2912,7 +2912,6 @@ F: softmmu/main.c
>  F: softmmu/cpus.c
>  F: softmmu/cpu-throttle.c
>  F: softmmu/cpu-timers.c
> -F: softmmu/icount.c
Would also be a maintainer switch

Otherwise,
Reviewed-by: Anton Johansson 



Re: [PATCH 10/11] accel/tcg: Make icount.o a target agnostic unit

2023-09-15 Thread Anton Johansson via
On 15/09/23, Philippe Mathieu-Daudé wrote:
> On 15/9/23 16:31, Anton Johansson wrote:
> > On 14/09/23, Philippe Mathieu-Daudé wrote:
> > > Remove the unused "exec/exec-all.h" header. There is
> > > no more target specific code in it: make it target
> > > agnostic (rename using the '-common' suffix). Since
> > > it is TCG specific, move it to accel/tcg, updating
> > > MAINTAINERS.
> > > 
> > > Signed-off-by: Philippe Mathieu-Daudé 
> > > ---
> > >   MAINTAINERS   | 1 -
> > >   softmmu/icount.c => accel/tcg/icount-common.c | 3 +--
> > >   accel/tcg/meson.build | 1 +
> > >   softmmu/meson.build   | 4 
> > >   4 files changed, 2 insertions(+), 7 deletions(-)
> > >   rename softmmu/icount.c => accel/tcg/icount-common.c (99%)
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index ff436dbf21..047d143b9d 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -2912,7 +2912,6 @@ F: softmmu/main.c
> > >   F: softmmu/cpus.c
> > >   F: softmmu/cpu-throttle.c
> > >   F: softmmu/cpu-timers.c
> > > -F: softmmu/icount.c
> > Would also be a maintainer switch
> 
> OK, now I understood your comment. I should have mentioned
> it in the commit description. This move from "Main loop"
> to "Overall TCG". Icount is a TCG feature.
> (Less work for Paolo, but more for Richard...)
Ah that makes sense, just wanted to make sure:)



Re: [PATCH v2 02/24] accel/tcg: Move CPUTLB definitions from cpu-defs.h

2023-09-14 Thread Anton Johansson via


On 9/14/23 04:44, Richard Henderson wrote:

Accept that we will consume space in CPUState for CONFIG_USER_ONLY,
since we cannot test CONFIG_SOFTMMU within hw/core/cpu.h.

Signed-off-by: Richard Henderson
---
  include/exec/cpu-defs.h | 150 
  include/hw/core/cpu.h   | 141 +
  2 files changed, 141 insertions(+), 150 deletions(-)

Reviewed-by: Anton Johansson 

[PATCH 11/11] accel/tcg: move ld/st helpers to ldst_common.c.inc

2023-09-12 Thread Anton Johansson via
A large chunk of ld/st functions are moved from cputlb.c and user-exec.c
to ldst_common.c.inc as their implementation is the same between both
modes.

Eventually, ldst_common.c.inc could be compiled into a separate
target-specific compilation unit, and be linked in with the targets.
Keeping CPUArchState usage out of cputlb.c (CPUArchState is primarily
used to access the mmu index in these functions).

Signed-off-by: Anton Johansson 
---
 accel/tcg/cputlb.c  | 214 --
 accel/tcg/user-exec.c   | 193 ---
 accel/tcg/ldst_common.c.inc | 225 
 3 files changed, 225 insertions(+), 407 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index ca69c369cc..cf4f50b188 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -2436,13 +2436,6 @@ static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, 
MemOpIdx oi,
 return do_ld_1(cpu, [0], l.mmu_idx, access_type, ra);
 }
 
-tcg_target_ulong helper_ldub_mmu(CPUArchState *env, uint64_t addr,
- MemOpIdx oi, uintptr_t retaddr)
-{
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
-return do_ld1_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
-}
-
 static uint16_t do_ld2_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
uintptr_t ra, MMUAccessType access_type)
 {
@@ -2468,13 +2461,6 @@ static uint16_t do_ld2_mmu(CPUState *cpu, vaddr addr, 
MemOpIdx oi,
 return ret;
 }
 
-tcg_target_ulong helper_lduw_mmu(CPUArchState *env, uint64_t addr,
- MemOpIdx oi, uintptr_t retaddr)
-{
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
-return do_ld2_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
-}
-
 static uint32_t do_ld4_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
uintptr_t ra, MMUAccessType access_type)
 {
@@ -2496,13 +2482,6 @@ static uint32_t do_ld4_mmu(CPUState *cpu, vaddr addr, 
MemOpIdx oi,
 return ret;
 }
 
-tcg_target_ulong helper_ldul_mmu(CPUArchState *env, uint64_t addr,
- MemOpIdx oi, uintptr_t retaddr)
-{
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
-return do_ld4_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
-}
-
 static uint64_t do_ld8_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
uintptr_t ra, MMUAccessType access_type)
 {
@@ -2524,36 +2503,6 @@ static uint64_t do_ld8_mmu(CPUState *cpu, vaddr addr, 
MemOpIdx oi,
 return ret;
 }
 
-uint64_t helper_ldq_mmu(CPUArchState *env, uint64_t addr,
-MemOpIdx oi, uintptr_t retaddr)
-{
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
-return do_ld8_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
-}
-
-/*
- * Provide signed versions of the load routines as well.  We can of course
- * avoid this for 64-bit data, or for 32-bit data on 32-bit host.
- */
-
-tcg_target_ulong helper_ldsb_mmu(CPUArchState *env, uint64_t addr,
- MemOpIdx oi, uintptr_t retaddr)
-{
-return (int8_t)helper_ldub_mmu(env, addr, oi, retaddr);
-}
-
-tcg_target_ulong helper_ldsw_mmu(CPUArchState *env, uint64_t addr,
- MemOpIdx oi, uintptr_t retaddr)
-{
-return (int16_t)helper_lduw_mmu(env, addr, oi, retaddr);
-}
-
-tcg_target_ulong helper_ldsl_mmu(CPUArchState *env, uint64_t addr,
- MemOpIdx oi, uintptr_t retaddr)
-{
-return (int32_t)helper_ldul_mmu(env, addr, oi, retaddr);
-}
-
 static Int128 do_ld16_mmu(CPUState *cpu, vaddr addr,
   MemOpIdx oi, uintptr_t ra)
 {
@@ -2619,81 +2568,6 @@ static Int128 do_ld16_mmu(CPUState *cpu, vaddr addr,
 return ret;
 }
 
-Int128 helper_ld16_mmu(CPUArchState *env, uint64_t addr,
-   uint32_t oi, uintptr_t retaddr)
-{
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
-return do_ld16_mmu(env_cpu(env), addr, oi, retaddr);
-}
-
-Int128 helper_ld_i128(CPUArchState *env, uint64_t addr, uint32_t oi)
-{
-return helper_ld16_mmu(env, addr, oi, GETPC());
-}
-
-/*
- * Load helpers for cpu_ldst.h.
- */
-
-static void plugin_load_cb(CPUArchState *env, abi_ptr addr, MemOpIdx oi)
-{
-qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
-}
-
-uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr addr, MemOpIdx oi, uintptr_t ra)
-{
-uint8_t ret;
-
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_UB);
-ret = do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
-plugin_load_cb(env, addr, oi);
-return ret;
-}
-
-uint16_t cpu_ldw_mmu(CPUArchState *env, abi_ptr addr,
- MemOpIdx oi, uintptr_t ra)
-{
-uint16_t ret;
-
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
-ret = do_ld2_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
-plugin_load_cb(env, addr, oi);
-return ret;
-}
-
-uint32_t 

[PATCH 09/11] tcg: Update env_tlb() comments

2023-09-12 Thread Anton Johansson via
Signed-off-by: Anton Johansson 
---
 tcg/aarch64/tcg-target.c.inc | 2 +-
 tcg/arm/tcg-target.c.inc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 0931a69448..d2f5ca5946 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1676,7 +1676,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, 
HostAddress *h,
 mask_type = (s->page_bits + s->tlb_dyn_max_bits > 32
  ? TCG_TYPE_I64 : TCG_TYPE_I32);
 
-/* Load env_tlb(env)->f[mmu_idx].{mask,table} into {tmp0,tmp1}. */
+/* Load cpu_tlb(cpu)->f[mmu_idx].{mask,table} into {tmp0,tmp1}. */
 QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
 QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, table) != 8);
 tcg_out_insn(s, 3314, LDP, TCG_REG_TMP0, TCG_REG_TMP1, TCG_AREG0,
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index acb5f23b54..9b96f5e7b5 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1420,7 +1420,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, 
HostAddress *h,
 ldst->addrlo_reg = addrlo;
 ldst->addrhi_reg = addrhi;
 
-/* Load env_tlb(env)->f[mmu_idx].{mask,table} into {r0,r1}.  */
+/* Load cpu_tlb(cpu)->f[mmu_idx].{mask,table} into {r0,r1}.  */
 QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
 QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, table) != 4);
 tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_AREG0, fast_off);
-- 
2.41.0




[PATCH 03/11] accel/tcg: Modify tlb_*() to use CPUState

2023-09-12 Thread Anton Johansson via
Changes tlb_*() functions to take CPUState instead of CPUArchState, as
they don't require the full CPUArchState. This makes it easier to
decouple target-(in)dependent code.

Signed-off-by: Anton Johansson 
---
 include/exec/cpu_ldst.h |   8 +-
 accel/tcg/cputlb.c  | 218 +++-
 2 files changed, 107 insertions(+), 119 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index da10ba1433..8d168f76ce 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -361,19 +361,19 @@ static inline uint64_t tlb_addr_write(const CPUTLBEntry 
*entry)
 }
 
 /* Find the TLB index corresponding to the mmu_idx + address pair.  */
-static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
+static inline uintptr_t tlb_index(CPUState *cpu, uintptr_t mmu_idx,
   vaddr addr)
 {
-uintptr_t size_mask = env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS;
+uintptr_t size_mask = cpu_tlb(cpu)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS;
 
 return (addr >> TARGET_PAGE_BITS) & size_mask;
 }
 
 /* Find the TLB entry corresponding to the mmu_idx + address pair.  */
-static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
+static inline CPUTLBEntry *tlb_entry(CPUState *cpu, uintptr_t mmu_idx,
  vaddr addr)
 {
-return _tlb(env)->f[mmu_idx].table[tlb_index(env, mmu_idx, addr)];
+return _tlb(cpu)->f[mmu_idx].table[tlb_index(cpu, mmu_idx, addr)];
 }
 
 #endif /* defined(CONFIG_USER_ONLY) */
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index c643d66190..213b3236bb 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -240,11 +240,11 @@ static void tlb_mmu_flush_locked(CPUTLBDesc *desc, 
CPUTLBDescFast *fast)
 memset(desc->vtable, -1, sizeof(desc->vtable));
 }
 
-static void tlb_flush_one_mmuidx_locked(CPUArchState *env, int mmu_idx,
+static void tlb_flush_one_mmuidx_locked(CPUState *cpu, int mmu_idx,
 int64_t now)
 {
-CPUTLBDesc *desc = _tlb(env)->d[mmu_idx];
-CPUTLBDescFast *fast = _tlb(env)->f[mmu_idx];
+CPUTLBDesc *desc = _tlb(cpu)->d[mmu_idx];
+CPUTLBDescFast *fast = _tlb(cpu)->f[mmu_idx];
 
 tlb_mmu_resize_locked(desc, fast, now);
 tlb_mmu_flush_locked(desc, fast);
@@ -262,41 +262,39 @@ static void tlb_mmu_init(CPUTLBDesc *desc, CPUTLBDescFast 
*fast, int64_t now)
 tlb_mmu_flush_locked(desc, fast);
 }
 
-static inline void tlb_n_used_entries_inc(CPUArchState *env, uintptr_t mmu_idx)
+static inline void tlb_n_used_entries_inc(CPUState *cpu, uintptr_t mmu_idx)
 {
-env_tlb(env)->d[mmu_idx].n_used_entries++;
+cpu_tlb(cpu)->d[mmu_idx].n_used_entries++;
 }
 
-static inline void tlb_n_used_entries_dec(CPUArchState *env, uintptr_t mmu_idx)
+static inline void tlb_n_used_entries_dec(CPUState *cpu, uintptr_t mmu_idx)
 {
-env_tlb(env)->d[mmu_idx].n_used_entries--;
+cpu_tlb(cpu)->d[mmu_idx].n_used_entries--;
 }
 
 void tlb_init(CPUState *cpu)
 {
-CPUArchState *env = cpu->env_ptr;
 int64_t now = get_clock_realtime();
 int i;
 
-qemu_spin_init(_tlb(env)->c.lock);
+qemu_spin_init(_tlb(cpu)->c.lock);
 
 /* All tlbs are initialized flushed. */
-env_tlb(env)->c.dirty = 0;
+cpu_tlb(cpu)->c.dirty = 0;
 
 for (i = 0; i < NB_MMU_MODES; i++) {
-tlb_mmu_init(_tlb(env)->d[i], _tlb(env)->f[i], now);
+tlb_mmu_init(_tlb(cpu)->d[i], _tlb(cpu)->f[i], now);
 }
 }
 
 void tlb_destroy(CPUState *cpu)
 {
-CPUArchState *env = cpu->env_ptr;
 int i;
 
-qemu_spin_destroy(_tlb(env)->c.lock);
+qemu_spin_destroy(_tlb(cpu)->c.lock);
 for (i = 0; i < NB_MMU_MODES; i++) {
-CPUTLBDesc *desc = _tlb(env)->d[i];
-CPUTLBDescFast *fast = _tlb(env)->f[i];
+CPUTLBDesc *desc = _tlb(cpu)->d[i];
+CPUTLBDescFast *fast = _tlb(cpu)->f[i];
 
 g_free(fast->table);
 g_free(desc->fulltlb);
@@ -328,11 +326,9 @@ void tlb_flush_counts(size_t *pfull, size_t *ppart, size_t 
*pelide)
 size_t full = 0, part = 0, elide = 0;
 
 CPU_FOREACH(cpu) {
-CPUArchState *env = cpu->env_ptr;
-
-full += qatomic_read(_tlb(env)->c.full_flush_count);
-part += qatomic_read(_tlb(env)->c.part_flush_count);
-elide += qatomic_read(_tlb(env)->c.elide_flush_count);
+full += qatomic_read(_tlb(cpu)->c.full_flush_count);
+part += qatomic_read(_tlb(cpu)->c.part_flush_count);
+elide += qatomic_read(_tlb(cpu)->c.elide_flush_count);
 }
 *pfull = full;
 *ppart = part;
@@ -341,7 +337,6 @@ void tlb_flush_counts(size_t *pfull, size_t *ppart, size_t 
*pelide)
 
 static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
 {
-CPUArchState *env = cpu->env_ptr;
 uint16_t asked = data.host_int;
 uint16_t all_dirty, work, to_clean;
 int64_t now = get_clock_realtime();
@@ -350,31 +345,31 @@ static void 

[PATCH 08/11] include/exec: Remove env_tlb()

2023-09-12 Thread Anton Johansson via
The function is no longer used to access the TLB, and has been replaced
by cpu_tlb().

Signed-off-by: Anton Johansson 
---
 include/exec/cpu-all.h | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index b03218d7d3..ee21f94969 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -484,17 +484,6 @@ static inline CPUNegativeOffsetState *cpu_neg(CPUState 
*cpu)
 return _cpu->neg;
 }
 
-/**
- * env_tlb(env)
- * @env: The architecture environment
- *
- * Return the CPUTLB state associated with the environment.
- */
-static inline CPUTLB *env_tlb(CPUArchState *env)
-{
-return _neg(env)->tlb;
-}
-
 /**
  * cpu_tlb(cpu)
  * @cpu: The generic CPUState
-- 
2.41.0




[PATCH 07/11] accel/tcg: Use CPUState in atomicity helpers

2023-09-12 Thread Anton Johansson via
Makes ldst_atomicity.c.inc almost target-independent, with the exception
of TARGET_PAGE_MASK, which will be addressed in a future patch.

Signed-off-by: Anton Johansson 
---
 accel/tcg/cputlb.c | 20 
 accel/tcg/user-exec.c  | 16 +++
 accel/tcg/ldst_atomicity.c.inc | 88 +-
 3 files changed, 62 insertions(+), 62 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index cbefea0dd6..5439ca1cf7 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -2209,7 +2209,7 @@ static uint64_t do_ld_whole_be8(CPUState *cpu, uintptr_t 
ra,
 MMULookupPageData *p, uint64_t ret_be)
 {
 int o = p->addr & 7;
-uint64_t x = load_atomic8_or_exit(cpu->env_ptr, ra, p->haddr - o);
+uint64_t x = load_atomic8_or_exit(cpu, ra, p->haddr - o);

 x = cpu_to_be64(x);
 x <<= o * 8;
@@ -2229,7 +2229,7 @@ static Int128 do_ld_whole_be16(CPUState *cpu, uintptr_t 
ra,
MMULookupPageData *p, uint64_t ret_be)
 {
 int o = p->addr & 15;
-Int128 x, y = load_atomic16_or_exit(cpu->env_ptr, ra, p->haddr - o);
+Int128 x, y = load_atomic16_or_exit(cpu, ra, p->haddr - o);
 int size = p->size;

 if (!HOST_BIG_ENDIAN) {
@@ -2373,7 +2373,7 @@ static uint16_t do_ld_2(CPUState *cpu, MMULookupPageData 
*p, int mmu_idx,
 }
 } else {
 /* Perform the load host endian, then swap if necessary. */
-ret = load_atom_2(cpu->env_ptr, ra, p->haddr, memop);
+ret = load_atom_2(cpu, ra, p->haddr, memop);
 if (memop & MO_BSWAP) {
 ret = bswap16(ret);
 }
@@ -2394,7 +2394,7 @@ static uint32_t do_ld_4(CPUState *cpu, MMULookupPageData 
*p, int mmu_idx,
 }
 } else {
 /* Perform the load host endian. */
-ret = load_atom_4(cpu->env_ptr, ra, p->haddr, memop);
+ret = load_atom_4(cpu, ra, p->haddr, memop);
 if (memop & MO_BSWAP) {
 ret = bswap32(ret);
 }
@@ -2415,7 +2415,7 @@ static uint64_t do_ld_8(CPUState *cpu, MMULookupPageData 
*p, int mmu_idx,
 }
 } else {
 /* Perform the load host endian. */
-ret = load_atom_8(cpu->env_ptr, ra, p->haddr, memop);
+ret = load_atom_8(cpu, ra, p->haddr, memop);
 if (memop & MO_BSWAP) {
 ret = bswap64(ret);
 }
@@ -2578,7 +2578,7 @@ static Int128 do_ld16_mmu(CPUState *cpu, vaddr addr,
 }
 } else {
 /* Perform the load host endian. */
-ret = load_atom_16(cpu->env_ptr, ra, l.page[0].haddr, l.memop);
+ret = load_atom_16(cpu, ra, l.page[0].haddr, l.memop);
 if (l.memop & MO_BSWAP) {
 ret = bswap128(ret);
 }
@@ -2893,7 +2893,7 @@ static void do_st_2(CPUState *cpu, MMULookupPageData *p, 
uint16_t val,
 if (memop & MO_BSWAP) {
 val = bswap16(val);
 }
-store_atom_2(cpu->env_ptr, ra, p->haddr, memop, val);
+store_atom_2(cpu, ra, p->haddr, memop, val);
 }
 }

@@ -2913,7 +2913,7 @@ static void do_st_4(CPUState *cpu, MMULookupPageData *p, 
uint32_t val,
 if (memop & MO_BSWAP) {
 val = bswap32(val);
 }
-store_atom_4(cpu->env_ptr, ra, p->haddr, memop, val);
+store_atom_4(cpu, ra, p->haddr, memop, val);
 }
 }

@@ -2933,7 +2933,7 @@ static void do_st_8(CPUState *cpu, MMULookupPageData *p, 
uint64_t val,
 if (memop & MO_BSWAP) {
 val = bswap64(val);
 }
-store_atom_8(cpu->env_ptr, ra, p->haddr, memop, val);
+store_atom_8(cpu, ra, p->haddr, memop, val);
 }
 }

@@ -3064,7 +3064,7 @@ static void do_st16_mmu(CPUState *cpu, vaddr addr, Int128 
val,
 if (l.memop & MO_BSWAP) {
 val = bswap128(val);
 }
-store_atom_16(cpu->env_ptr, ra, l.page[0].haddr, l.memop, val);
+store_atom_16(cpu, ra, l.page[0].haddr, l.memop, val);
 }
 return;
 }
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index d2daeafbab..f9f5cd1770 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -1002,7 +1002,7 @@ static uint16_t do_ld2_mmu(CPUArchState *env, abi_ptr 
addr,
 tcg_debug_assert((mop & MO_SIZE) == MO_16);
 cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
 haddr = cpu_mmu_lookup(env, addr, mop, ra, MMU_DATA_LOAD);
-ret = load_atom_2(env, ra, haddr, mop);
+ret = load_atom_2(env_cpu(env), ra, haddr, mop);
 clear_helper_retaddr();

 if (mop & MO_BSWAP) {
@@ -1040,7 +1040,7 @@ static uint32_t do_ld4_mmu(CPUArchState *env, abi_ptr 
addr,
 tcg_debug_assert((mop & MO_SIZE) == MO_32);
 cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
 haddr = cpu_mmu_lookup(env, addr, mop, ra, MMU_DATA_LOAD);
-ret = load_atom_4(env, ra, haddr, mop);
+ret = load_atom_4(env_cpu(env), ra, haddr, mop);
 clear_helper_retaddr();

 if (mop & MO_BSWAP) {
@@ -1078,7 +1078,7 @@ 

[PATCH 02/11] include: Introduce tlb_ptr field to CPUState

2023-09-12 Thread Anton Johansson via
Adds a CPUTLB * field to CPUState in order to access the TLB without
knowledge of the ArchCPU struct layout. A cpu_tlb(CPUState *) function
is added for ease of access.

Signed-off-by: Anton Johansson 
---
 include/exec/cpu-all.h | 12 
 include/hw/core/cpu.h  |  6 ++
 2 files changed, 18 insertions(+)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index c2c62160c6..b03218d7d3 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -435,6 +435,7 @@ static inline void cpu_set_cpustate_pointers(ArchCPU *cpu)
 {
 cpu->parent_obj.env_ptr = >env;
 cpu->parent_obj.icount_decr_ptr = >neg.icount_decr;
+cpu->parent_obj.tlb_ptr = >neg.tlb;
 }
 
 /**
@@ -494,4 +495,15 @@ static inline CPUTLB *env_tlb(CPUArchState *env)
 return _neg(env)->tlb;
 }
 
+/**
+ * cpu_tlb(cpu)
+ * @cpu: The generic CPUState
+ *
+ * Return the CPUTLB state associated with the cpu.
+ */
+static inline CPUTLB *cpu_tlb(CPUState *cpu)
+{
+return cpu->tlb_ptr;
+}
+
 #endif /* CPU_ALL_H */
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 92a4234439..dd31303480 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -238,7 +238,12 @@ typedef struct SavedIOTLB {
 } SavedIOTLB;
 #endif
 
+/* see include/exec/cpu-defs.h */
+struct CPUTLB;
+
+/* see include/sysemu/kvm_int.h */
 struct KVMState;
+/* see linux-headers/linux/kvm.h */
 struct kvm_run;
 
 /* work queue */
@@ -372,6 +377,7 @@ struct CPUState {
 
 CPUArchState *env_ptr;
 IcountDecr *icount_decr_ptr;
+struct CPUTLB *tlb_ptr;
 
 CPUJumpCache *tb_jmp_cache;
 
-- 
2.41.0




[PATCH 05/11] accel/tcg: Modifies memory access functions to use CPUState

2023-09-12 Thread Anton Johansson via
do_[ld|st]*() and mmu_lookup*() are changed to use CPUState over
CPUArchState, moving the target-dependence to the target-facing facing
cpu_[ld|st] functions.

Signed-off-by: Anton Johansson 
---
 accel/tcg/cputlb.c | 324 ++---
 1 file changed, 161 insertions(+), 163 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 20ea2e2395..ebd174e23d 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1367,11 +1367,10 @@ static void save_iotlb_data(CPUState *cs, 
MemoryRegionSection *section,
 #endif
 }
 
-static uint64_t io_readx(CPUArchState *env, CPUTLBEntryFull *full,
+static uint64_t io_readx(CPUState *cpu, CPUTLBEntryFull *full,
  int mmu_idx, vaddr addr, uintptr_t retaddr,
  MMUAccessType access_type, MemOp op)
 {
-CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
 MemoryRegionSection *section;
 MemoryRegion *mr;
@@ -1408,11 +1407,10 @@ static uint64_t io_readx(CPUArchState *env, 
CPUTLBEntryFull *full,
 return val;
 }
 
-static void io_writex(CPUArchState *env, CPUTLBEntryFull *full,
+static void io_writex(CPUState *cpu, CPUTLBEntryFull *full,
   int mmu_idx, uint64_t val, vaddr addr,
   uintptr_t retaddr, MemOp op)
 {
-CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
 MemoryRegionSection *section;
 MemoryRegion *mr;
@@ -1776,7 +1774,7 @@ typedef struct MMULookupLocals {
 
 /**
  * mmu_lookup1: translate one page
- * @env: cpu context
+ * @cpu: generic cpu state
  * @data: lookup parameters
  * @mmu_idx: virtual address context
  * @access_type: load/store/code
@@ -1787,12 +1785,12 @@ typedef struct MMULookupLocals {
  * tlb_fill will longjmp out.  Return true if the softmmu tlb for
  * @mmu_idx may have resized.
  */
-static bool mmu_lookup1(CPUArchState *env, MMULookupPageData *data,
+static bool mmu_lookup1(CPUState *cpu, MMULookupPageData *data,
 int mmu_idx, MMUAccessType access_type, uintptr_t ra)
 {
 vaddr addr = data->addr;
-uintptr_t index = tlb_index(env_cpu(env), mmu_idx, addr);
-CPUTLBEntry *entry = tlb_entry(env_cpu(env), mmu_idx, addr);
+uintptr_t index = tlb_index(cpu, mmu_idx, addr);
+CPUTLBEntry *entry = tlb_entry(cpu, mmu_idx, addr);
 uint64_t tlb_addr = tlb_read_idx(entry, access_type);
 bool maybe_resized = false;
 CPUTLBEntryFull *full;
@@ -1800,17 +1798,17 @@ static bool mmu_lookup1(CPUArchState *env, 
MMULookupPageData *data,
 
 /* If the TLB entry is for a different page, reload and try again.  */
 if (!tlb_hit(tlb_addr, addr)) {
-if (!victim_tlb_hit(env_cpu(env), mmu_idx, index, access_type,
+if (!victim_tlb_hit(cpu, mmu_idx, index, access_type,
 addr & TARGET_PAGE_MASK)) {
-tlb_fill(env_cpu(env), addr, data->size, access_type, mmu_idx, ra);
+tlb_fill(cpu, addr, data->size, access_type, mmu_idx, ra);
 maybe_resized = true;
-index = tlb_index(env_cpu(env), mmu_idx, addr);
-entry = tlb_entry(env_cpu(env), mmu_idx, addr);
+index = tlb_index(cpu, mmu_idx, addr);
+entry = tlb_entry(cpu, mmu_idx, addr);
 }
 tlb_addr = tlb_read_idx(entry, access_type) & ~TLB_INVALID_MASK;
 }
 
-full = _tlb(env)->d[mmu_idx].fulltlb[index];
+full = _tlb(cpu)->d[mmu_idx].fulltlb[index];
 flags = tlb_addr & (TLB_FLAGS_MASK & ~TLB_FORCE_SLOW);
 flags |= full->slow_flags[access_type];
 
@@ -1824,7 +1822,7 @@ static bool mmu_lookup1(CPUArchState *env, 
MMULookupPageData *data,
 
 /**
  * mmu_watch_or_dirty
- * @env: cpu context
+ * @cpu: generic cpu state
  * @data: lookup parameters
  * @access_type: load/store/code
  * @ra: return address into tcg generated code, or 0
@@ -1832,7 +1830,7 @@ static bool mmu_lookup1(CPUArchState *env, 
MMULookupPageData *data,
  * Trigger watchpoints for @data.addr:@data.size;
  * record writes to protected clean pages.
  */
-static void mmu_watch_or_dirty(CPUArchState *env, MMULookupPageData *data,
+static void mmu_watch_or_dirty(CPUState *cpu, MMULookupPageData *data,
MMUAccessType access_type, uintptr_t ra)
 {
 CPUTLBEntryFull *full = data->full;
@@ -1843,13 +1841,13 @@ static void mmu_watch_or_dirty(CPUArchState *env, 
MMULookupPageData *data,
 /* On watchpoint hit, this will longjmp out.  */
 if (flags & TLB_WATCHPOINT) {
 int wp = access_type == MMU_DATA_STORE ? BP_MEM_WRITE : BP_MEM_READ;
-cpu_check_watchpoint(env_cpu(env), addr, size, full->attrs, wp, ra);
+cpu_check_watchpoint(cpu, addr, size, full->attrs, wp, ra);
 flags &= ~TLB_WATCHPOINT;
 }
 
 /* Note that notdirty is only set for writes. */
 if (flags & TLB_NOTDIRTY) {
-notdirty_write(env_cpu(env), addr, size, full, ra);
+notdirty_write(cpu, addr, size, full, ra);
 flags &= ~TLB_NOTDIRTY;
 

[PATCH 04/11] accel/tcg: Modify probe_access_internal() to use CPUState

2023-09-12 Thread Anton Johansson via
probe_access_internal() is changed to instead take the generic CPUState
over CPUArchState, in order to lessen the target-specific coupling of
cputlb.c. Note: probe_access*() also don't need the full CPUArchState,
but aren't touched in this patch as they are target-facing.

Signed-off-by: Anton Johansson 
---
 accel/tcg/cputlb.c | 46 +++---
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 213b3236bb..20ea2e2395 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1504,27 +1504,24 @@ static void notdirty_write(CPUState *cpu, vaddr 
mem_vaddr, unsigned size,
 }
 }
 
-static int probe_access_internal(CPUArchState *env, vaddr addr,
+static int probe_access_internal(CPUState *cpu, vaddr addr,
  int fault_size, MMUAccessType access_type,
  int mmu_idx, bool nonfault,
  void **phost, CPUTLBEntryFull **pfull,
  uintptr_t retaddr, bool check_mem_cbs)
 {
-uintptr_t index = tlb_index(env_cpu(env), mmu_idx, addr);
-CPUTLBEntry *entry = tlb_entry(env_cpu(env), mmu_idx, addr);
+uintptr_t index = tlb_index(cpu, mmu_idx, addr);
+CPUTLBEntry *entry = tlb_entry(cpu, mmu_idx, addr);
 uint64_t tlb_addr = tlb_read_idx(entry, access_type);
 vaddr page_addr = addr & TARGET_PAGE_MASK;
 int flags = TLB_FLAGS_MASK & ~TLB_FORCE_SLOW;
-bool force_mmio = check_mem_cbs && 
cpu_plugin_mem_cbs_enabled(env_cpu(env));
+bool force_mmio = check_mem_cbs && cpu_plugin_mem_cbs_enabled(cpu);
 CPUTLBEntryFull *full;
 
 if (!tlb_hit_page(tlb_addr, page_addr)) {
-if (!victim_tlb_hit(env_cpu(env), mmu_idx, index,
-access_type, page_addr)) {
-CPUState *cs = env_cpu(env);
-
-if (!cs->cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type,
-   mmu_idx, nonfault, retaddr)) {
+if (!victim_tlb_hit(cpu, mmu_idx, index, access_type, page_addr)) {
+if (!cpu->cc->tcg_ops->tlb_fill(cpu, addr, fault_size, access_type,
+mmu_idx, nonfault, retaddr)) {
 /* Non-faulting page table read failed.  */
 *phost = NULL;
 *pfull = NULL;
@@ -1532,8 +1529,8 @@ static int probe_access_internal(CPUArchState *env, vaddr 
addr,
 }
 
 /* TLB resize via tlb_fill may have moved the entry.  */
-index = tlb_index(env_cpu(env), mmu_idx, addr);
-entry = tlb_entry(env_cpu(env), mmu_idx, addr);
+index = tlb_index(cpu, mmu_idx, addr);
+entry = tlb_entry(cpu, mmu_idx, addr);
 
 /*
  * With PAGE_WRITE_INV, we set TLB_INVALID_MASK immediately,
@@ -1546,7 +1543,7 @@ static int probe_access_internal(CPUArchState *env, vaddr 
addr,
 }
 flags &= tlb_addr;
 
-*pfull = full = _tlb(env)->d[mmu_idx].fulltlb[index];
+*pfull = full = _tlb(cpu)->d[mmu_idx].fulltlb[index];
 flags |= full->slow_flags[access_type];
 
 /* Fold all "mmio-like" bits into TLB_MMIO.  This is not RAM.  */
@@ -1567,8 +1564,9 @@ int probe_access_full(CPUArchState *env, vaddr addr, int 
size,
   bool nonfault, void **phost, CPUTLBEntryFull **pfull,
   uintptr_t retaddr)
 {
-int flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
-  nonfault, phost, pfull, retaddr, true);
+int flags = probe_access_internal(env_cpu(env), addr, size, access_type,
+  mmu_idx, nonfault, phost, pfull, retaddr,
+  true);
 
 /* Handle clean RAM pages.  */
 if (unlikely(flags & TLB_NOTDIRTY)) {
@@ -1590,8 +1588,8 @@ int probe_access_full_mmu(CPUArchState *env, vaddr addr, 
int size,
 phost = phost ? phost : _phost;
 pfull = pfull ? pfull : _tlb;
 
-int flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
-  true, phost, pfull, 0, false);
+int flags = probe_access_internal(env_cpu(env), addr, size, access_type,
+  mmu_idx, true, phost, pfull, 0, false);
 
 /* Handle clean RAM pages.  */
 if (unlikely(flags & TLB_NOTDIRTY)) {
@@ -1611,8 +1609,9 @@ int probe_access_flags(CPUArchState *env, vaddr addr, int 
size,
 
 g_assert(-(addr | TARGET_PAGE_MASK) >= size);
 
-flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
-  nonfault, phost, , retaddr, true);
+flags = probe_access_internal(env_cpu(env), addr, size, access_type,
+  mmu_idx, nonfault, phost, , retaddr,
+  true);
 
 /* Handle clean RAM pages. */
 if (unlikely(flags & 

[PATCH 06/11] accel/tcg: Modify atomic_mmu_lookup() to use CPUState

2023-09-12 Thread Anton Johansson via
The goal is to (in the future) allow for per-target compilation of
functions in atomic_template.h whilst atomic_mmu_lookup() and cputlb.c
are compiled once-per user- or system mode.

Signed-off-by: Anton Johansson 
---
 accel/tcg/atomic_template.h | 20 
 accel/tcg/cputlb.c  | 26 +-
 accel/tcg/user-exec.c   |  8 
 3 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index 84c08b1425..1dc2151daf 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -73,7 +73,8 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
   ABI_TYPE cmpv, ABI_TYPE newv,
   MemOpIdx oi, uintptr_t retaddr)
 {
-DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
+DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
+ DATA_SIZE, retaddr);
 DATA_TYPE ret;

 #if DATA_SIZE == 16
@@ -90,7 +91,8 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
 ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
MemOpIdx oi, uintptr_t retaddr)
 {
-DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
+DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
+ DATA_SIZE, retaddr);
 DATA_TYPE ret;

 ret = qatomic_xchg__nocheck(haddr, val);
@@ -104,7 +106,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr,
\
 ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
 {   \
 DATA_TYPE *haddr, ret;  \
-haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);   \
+haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr);   \
 ret = qatomic_##X(haddr, val);  \
 ATOMIC_MMU_CLEANUP; \
 atomic_trace_rmw_post(env, addr, oi);   \
@@ -135,7 +137,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr,
\
 ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
 {   \
 XDATA_TYPE *haddr, cmp, old, new, val = xval;   \
-haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);   \
+haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr);   \
 smp_mb();   \
 cmp = qatomic_read__nocheck(haddr); \
 do {\
@@ -176,7 +178,8 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr 
addr,
   ABI_TYPE cmpv, ABI_TYPE newv,
   MemOpIdx oi, uintptr_t retaddr)
 {
-DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
+DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
+ DATA_SIZE, retaddr);
 DATA_TYPE ret;

 #if DATA_SIZE == 16
@@ -193,7 +196,8 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr 
addr,
 ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
MemOpIdx oi, uintptr_t retaddr)
 {
-DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);
+DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
+ DATA_SIZE, retaddr);
 ABI_TYPE ret;

 ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
@@ -207,7 +211,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr,
\
 ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
 {   \
 DATA_TYPE *haddr, ret;  \
-haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);   \
+haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr);   \
 ret = qatomic_##X(haddr, BSWAP(val));   \
 ATOMIC_MMU_CLEANUP; \
 atomic_trace_rmw_post(env, addr, oi);   \
@@ -235,7 +239,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr,
\
 ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
 {   \
 XDATA_TYPE *haddr, ldo, ldn, old, new, val = xval;  \
-haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, retaddr);   \
+haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr);   \
 

[PATCH 10/11] accel/tcg: Unify user and softmmu do_[st|ld]*_mmu()

2023-09-12 Thread Anton Johansson via
The prototype of do_[st|ld]*_mmu() is unified between system- and
user-mode allowing a large chunk of helper_[st|ld]*() and cpu_[st|ld]*()
functions to be expressed in same manner between both modes. These
functions will be moved to ldst_common.c.inc in a following commit.

Signed-off-by: Anton Johansson 
---
 accel/tcg/cputlb.c|  16 ++--
 accel/tcg/user-exec.c | 183 --
 2 files changed, 117 insertions(+), 82 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 5439ca1cf7..ca69c369cc 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -2937,18 +2937,24 @@ static void do_st_8(CPUState *cpu, MMULookupPageData 
*p, uint64_t val,
 }
 }
 
-void helper_stb_mmu(CPUArchState *env, uint64_t addr, uint32_t val,
-MemOpIdx oi, uintptr_t ra)
+static void do_st1_mmu(CPUState *cpu, vaddr addr, uint8_t val,
+   MemOpIdx oi, uintptr_t ra)
 {
 MMULookupLocals l;
 bool crosspage;
 
-tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
 cpu_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
-crosspage = mmu_lookup(env_cpu(env), addr, oi, ra, MMU_DATA_STORE, );
+crosspage = mmu_lookup(cpu, addr, oi, ra, MMU_DATA_STORE, );
 tcg_debug_assert(!crosspage);
 
-do_st_1(env_cpu(env), [0], val, l.mmu_idx, ra);
+do_st_1(cpu, [0], val, l.mmu_idx, ra);
+}
+
+void helper_stb_mmu(CPUArchState *env, uint64_t addr, uint32_t val,
+MemOpIdx oi, uintptr_t ra)
+{
+tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
+do_st1_mmu(env_cpu(env), addr, val, oi, ra);
 }
 
 static void do_st2_mmu(CPUState *cpu, vaddr addr, uint16_t val,
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index f9f5cd1770..a6593d0e0f 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -941,7 +941,7 @@ void page_reset_target_data(target_ulong start, 
target_ulong last) { }
 
 /* The softmmu versions of these helpers are in cputlb.c.  */
 
-static void *cpu_mmu_lookup(CPUArchState *env, vaddr addr,
+static void *cpu_mmu_lookup(CPUState *cpu, vaddr addr,
 MemOp mop, uintptr_t ra, MMUAccessType type)
 {
 int a_bits = get_alignment_bits(mop);
@@ -949,25 +949,24 @@ static void *cpu_mmu_lookup(CPUArchState *env, vaddr addr,
 
 /* Enforce guest required alignment.  */
 if (unlikely(addr & ((1 << a_bits) - 1))) {
-cpu_loop_exit_sigbus(env_cpu(env), addr, type, ra);
+cpu_loop_exit_sigbus(cpu, addr, type, ra);
 }
 
-ret = g2h(env_cpu(env), addr);
+ret = g2h(cpu, addr);
 set_helper_retaddr(ra);
 return ret;
 }
 
 #include "ldst_atomicity.c.inc"
 
-static uint8_t do_ld1_mmu(CPUArchState *env, abi_ptr addr,
-  MemOp mop, uintptr_t ra)
+static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
+  uintptr_t ra, MMUAccessType access_type)
 {
 void *haddr;
 uint8_t ret;
 
-tcg_debug_assert((mop & MO_SIZE) == MO_8);
 cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
-haddr = cpu_mmu_lookup(env, addr, mop, ra, MMU_DATA_LOAD);
+haddr = cpu_mmu_lookup(cpu, addr, get_memop(oi), ra, access_type);
 ret = ldub_p(haddr);
 clear_helper_retaddr();
 return ret;
@@ -976,33 +975,38 @@ static uint8_t do_ld1_mmu(CPUArchState *env, abi_ptr addr,
 tcg_target_ulong helper_ldub_mmu(CPUArchState *env, uint64_t addr,
  MemOpIdx oi, uintptr_t ra)
 {
-return do_ld1_mmu(env, addr, get_memop(oi), ra);
+tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
+return do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
 }
 
 tcg_target_ulong helper_ldsb_mmu(CPUArchState *env, uint64_t addr,
  MemOpIdx oi, uintptr_t ra)
 {
-return (int8_t)do_ld1_mmu(env, addr, get_memop(oi), ra);
+tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
+return (int8_t)do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
 }
 
 uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr addr,
 MemOpIdx oi, uintptr_t ra)
 {
-uint8_t ret = do_ld1_mmu(env, addr, get_memop(oi), ra);
+uint8_t ret;
+
+tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
+ret = do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
 return ret;
 }
 
-static uint16_t do_ld2_mmu(CPUArchState *env, abi_ptr addr,
-   MemOp mop, uintptr_t ra)
+static uint16_t do_ld2_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
+   uintptr_t ra, MMUAccessType access_type)
 {
 void *haddr;
 uint16_t ret;
+MemOp mop = get_memop(oi);
 
-tcg_debug_assert((mop & MO_SIZE) == MO_16);
 cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
-haddr = cpu_mmu_lookup(env, addr, mop, ra, MMU_DATA_LOAD);
-ret = load_atom_2(env_cpu(env), ra, haddr, mop);
+haddr = cpu_mmu_lookup(cpu, addr, mop, ra, 

[PATCH 01/11] target/arm: Replace TARGET_PAGE_ENTRY_EXTRA

2023-09-12 Thread Anton Johansson via
TARGET_PAGE_ENTRY_EXTRA is a macro that allows guests to specify additional
fields for caching with the full TLB entry.  This macro is replaced with
a union in CPUTLBEntryFull, thus making CPUTLB target-agnostic at the
cost of slightly inflated CPUTLBEntryFull for non-arm guests.

Note, this is needed to ensure that fields in CPUTLB don't vary in
offset between various targets.

(arm is the only guest actually making use of this feature.)

Signed-off-by: Anton Johansson 
---
 include/exec/cpu-defs.h| 18 +++---
 target/arm/cpu-param.h | 12 
 target/arm/ptw.c   |  4 ++--
 target/arm/tcg/mte_helper.c|  2 +-
 target/arm/tcg/sve_helper.c|  2 +-
 target/arm/tcg/tlb_helper.c|  4 ++--
 target/arm/tcg/translate-a64.c |  2 +-
 7 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index fb4c8d480f..0a600a312b 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -135,9 +135,21 @@ typedef struct CPUTLBEntryFull {
  * This may be used to cache items from the guest cpu
  * page tables for later use by the implementation.
  */
-#ifdef TARGET_PAGE_ENTRY_EXTRA
-TARGET_PAGE_ENTRY_EXTRA
-#endif
+union {
+/*
+ * Cache the attrs and shareability fields from the page table entry.
+ *
+ * For ARMMMUIdx_Stage2*, pte_attrs is the S2 descriptor bits [5:2].
+ * Otherwise, pte_attrs is the same as the MAIR_EL1 8-bit format.
+ * For shareability and guarded, as in the SH and GP fields 
respectively
+ * of the VMSAv8-64 PTEs.
+ */
+struct {
+uint8_t pte_attrs;
+uint8_t shareability;
+bool guarded;
+} arm;
+} extra;
 } CPUTLBEntryFull;
 #endif /* CONFIG_SOFTMMU */
 
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index b3b35f7aa1..f9b462a98f 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -31,18 +31,6 @@
 # define TARGET_PAGE_BITS_VARY
 # define TARGET_PAGE_BITS_MIN  10
 
-/*
- * Cache the attrs and shareability fields from the page table entry.
- *
- * For ARMMMUIdx_Stage2*, pte_attrs is the S2 descriptor bits [5:2].
- * Otherwise, pte_attrs is the same as the MAIR_EL1 8-bit format.
- * For shareability and guarded, as in the SH and GP fields respectively
- * of the VMSAv8-64 PTEs.
- */
-# define TARGET_PAGE_ENTRY_EXTRA  \
-uint8_t pte_attrs;\
-uint8_t shareability; \
-bool guarded;
 #endif
 
 #endif
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index bfbab26b9b..95db9ec4c3 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -579,7 +579,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate 
*ptw,
 }
 ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK);
 ptw->out_rw = full->prot & PAGE_WRITE;
-pte_attrs = full->pte_attrs;
+pte_attrs = full->extra.arm.pte_attrs;
 ptw->out_space = full->attrs.space;
 #else
 g_assert_not_reached();
@@ -2036,7 +2036,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
S1Translate *ptw,
 
 /* When in aarch64 mode, and BTI is enabled, remember GP in the TLB. */
 if (aarch64 && cpu_isar_feature(aa64_bti, cpu)) {
-result->f.guarded = extract64(attrs, 50, 1); /* GP */
+result->f.extra.arm.guarded = extract64(attrs, 50, 1); /* GP */
 }
 }
 
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
index b23d11563a..dba21cc4d6 100644
--- a/target/arm/tcg/mte_helper.c
+++ b/target/arm/tcg/mte_helper.c
@@ -124,7 +124,7 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int 
ptr_mmu_idx,
 assert(!(flags & TLB_INVALID_MASK));
 
 /* If the virtual page MemAttr != Tagged, access unchecked. */
-if (full->pte_attrs != 0xf0) {
+if (full->extra.arm.pte_attrs != 0xf0) {
 return NULL;
 }
 
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
index 7c103fc9f7..f006d152cc 100644
--- a/target/arm/tcg/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
@@ -5373,7 +5373,7 @@ bool sve_probe_page(SVEHostPage *info, bool nofault, 
CPUARMState *env,
 info->tagged = (flags & PAGE_ANON) && (flags & PAGE_MTE);
 #else
 info->attrs = full->attrs;
-info->tagged = full->pte_attrs == 0xf0;
+info->tagged = full->extra.arm.pte_attrs == 0xf0;
 #endif
 
 /* Ensure that info->host[] is relative to addr, not addr + mem_off. */
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
index b22b2a4c6e..59bff8b452 100644
--- a/target/arm/tcg/tlb_helper.c
+++ b/target/arm/tcg/tlb_helper.c
@@ -334,8 +334,8 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 address &= TARGET_PAGE_MASK;
 }
 
-res.f.pte_attrs = res.cacheattrs.attrs;
-res.f.shareability = res.cacheattrs.shareability;
+res.f.extra.arm.pte_attrs = res.cacheattrs.attrs;
+ 

[PATCH 00/11] Reduce usage of CPUArchState in cputlb.c

2023-09-12 Thread Anton Johansson via
This patchset reduces the dependence of cputlb.c on the full
CPUArchState, instead replacing it with the generic CPUState. Target-
facing functions such as probe_access(), cpu_ld*(), etc. are not
modified in this patchset, the idea is to try and isolate all usage of
CPUArchState into smaller wrapper functions that can eventually be
compiled and linked into the target, whilst keeping accel/tcg/
target-independent.

Anton Johansson (11):
  target/arm: Replace TARGET_PAGE_ENTRY_EXTRA
  include: Introduce tlb_ptr field to CPUState
  accel/tcg: Modify tlb_*() to use CPUState
  accel/tcg: Modify probe_access_internal() to use CPUState
  accel/tcg: Modifies memory access functions to use CPUState
  accel/tcg: Modify atomic_mmu_lookup() to use CPUState
  accel/tcg: Use CPUState in atomicity helpers
  include/exec: Remove env_tlb()
  tcg: Update env_tlb() comments
  accel/tcg: Unify user and softmmu do_[st|ld]*_mmu()
  accel/tcg: move ld/st helpers to ldst_common.c.inc

 accel/tcg/atomic_template.h|  20 +-
 include/exec/cpu-all.h |  11 +-
 include/exec/cpu-defs.h|  18 +-
 include/exec/cpu_ldst.h|   8 +-
 include/hw/core/cpu.h  |   6 +
 target/arm/cpu-param.h |  12 -
 accel/tcg/cputlb.c | 756 -
 accel/tcg/user-exec.c  | 276 +++-
 target/arm/ptw.c   |   4 +-
 target/arm/tcg/mte_helper.c|   2 +-
 target/arm/tcg/sve_helper.c|   2 +-
 target/arm/tcg/tlb_helper.c|   4 +-
 target/arm/tcg/translate-a64.c |   2 +-
 accel/tcg/ldst_atomicity.c.inc |  88 ++--
 accel/tcg/ldst_common.c.inc| 225 ++
 tcg/aarch64/tcg-target.c.inc   |   2 +-
 tcg/arm/tcg-target.c.inc   |   2 +-
 17 files changed, 644 insertions(+), 794 deletions(-)

--
2.41.0



Re: [PATCH 05/11] accel/tcg: Modifies memory access functions to use CPUState

2023-09-13 Thread Anton Johansson via

On 9/12/23 21:34, Richard Henderson wrote:


On 9/12/23 08:34, Anton Johansson wrote:

do_[ld|st]*() and mmu_lookup*() are changed to use CPUState over
CPUArchState, moving the target-dependence to the target-facing facing
cpu_[ld|st] functions.

Signed-off-by: Anton Johansson 
---
  accel/tcg/cputlb.c | 324 ++---
  1 file changed, 161 insertions(+), 163 deletions(-)


So... what's your ultimate plan here?

At the moment through patches 5-11, all you do is take CPUArchState, 
discard knowledge of it via CPUState, and then recover knowledge of it 
via cpu->tlb_ptr.


I agree that *something* has to happen in order to allow these entry 
points to be used by multiple cpu types simultaneously, but there must 
be a plan.


Is it to have tcg generated code perform env_cpu() inline before the 
call?  That's just pointer arithmetic, so it's certainly an easy option.



My bad, I wasn't expressing this clearly enough, but yes that is
more or less the idea.  We need full access to env for two things:
getting to CPUState, and getting the mmu_idx.  This needs to happen
on the target side, somehow.  My ideas here are:

    For non-helpers (e.g. cpu_ldb_mmu):
    - These functions are just thin wrappers around
  do_[ld|st]*_mmu(), env_cpu() and cpu_mmu_index(),
  and can be compiled with each target;
    - or make these functions take CPUState, and explicitly
  call env_cpu on the target side. Functions needing
  to call cpu_mmu_index() can be compiled with the target
  (~20 small functions);
    - or, Minimize calls to env_cpu() and cpu_mmu_index(), as
  we have done, and make them non-inline so they can work
  on opaque pointers.

    For helpers (helper_ldub_mmu):
    - Either compile with the target as with non-helpers
  since these are also thin wrappers;
    - or allow helpers to only accept CPUState and
  automatically convert env -> cpu when calling
  (what you suggested)

Other ideas and approaches are ofc very welcome!:)

--
Anton Johansson,
rev.ng Labs Srl.




Re: [PATCH 02/11] include: Introduce tlb_ptr field to CPUState

2023-09-13 Thread Anton Johansson via




On 9/12/23 08:34, Anton Johansson wrote:

  IcountDecr *icount_decr_ptr;
+    struct CPUTLB *tlb_ptr;


These are both in CPUNegativeOffsetState.
We might as well use that pointer instead.


r~


Ah, good point.

--
Anton Johansson,
rev.ng Labs Srl.




Re: [PATCH 03/11] accel/tcg: Modify tlb_*() to use CPUState

2023-09-13 Thread Anton Johansson via




On 9/12/23 08:34, Anton Johansson wrote:

Changes tlb_*() functions to take CPUState instead of CPUArchState, as
they don't require the full CPUArchState. This makes it easier to
decouple target-(in)dependent code.

Signed-off-by: Anton Johansson 
---
  include/exec/cpu_ldst.h |   8 +-
  accel/tcg/cputlb.c  | 218 +++-
  2 files changed, 107 insertions(+), 119 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index da10ba1433..8d168f76ce 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -361,19 +361,19 @@ static inline uint64_t tlb_addr_write(const 
CPUTLBEntry *entry)

  }
    /* Find the TLB index corresponding to the mmu_idx + address 
pair.  */

-static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
+static inline uintptr_t tlb_index(CPUState *cpu, uintptr_t mmu_idx,
    vaddr addr)
  {
-    uintptr_t size_mask = env_tlb(env)->f[mmu_idx].mask >> 
CPU_TLB_ENTRY_BITS;
+    uintptr_t size_mask = cpu_tlb(cpu)->f[mmu_idx].mask >> 
CPU_TLB_ENTRY_BITS;


No, I think this is a bad idea, because it bakes an extra memory 
indirection into very fundamental routines.


If we change anything here, we should pass in CPUTLB.

Yeah, you're right. I'll pass CPUTLB instead, or do you have another idea?

Thanks a lot for the input!

--
Anton Johansson,
rev.ng Labs Srl.




Re: [PATCH v2 07/24] accel/tcg: Validate placement of CPUNegativeOffsetState

2023-09-14 Thread Anton Johansson via



On 9/14/23 04:44, Richard Henderson wrote:

Verify that the distance between CPUNegativeOffsetState and
CPUArchState is no greater than any alignment requirements.

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

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index c2c62160c6..86a7452b0d 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -459,6 +459,12 @@ static inline CPUState *env_cpu(CPUArchState *env)
  return _archcpu(env)->parent_obj;
  }
  
+/*

+ * Validate placement of CPUNegativeOffsetState.
+ */
+QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) - offsetof(ArchCPU, neg) >=
+  sizeof(CPUNegativeOffsetState) + __alignof(CPUArchState));
+
  /**
   * env_neg(env)
   * @env: The architecture environment

Reviewed-by: Anton Johansson 



Re: [PATCH v2 09/24] accel/tcg: Remove CPUState.icount_decr_ptr

2023-09-14 Thread Anton Johansson via



On 9/14/23 04:44, Richard Henderson wrote:

We can now access icount_decr directly.

Signed-off-by: Richard Henderson 
---
  include/exec/cpu-all.h | 1 -
  include/hw/core/cpu.h  | 2 --
  hw/core/cpu-common.c   | 4 ++--
  3 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index c3c78ed8ab..3b01e4ee25 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -434,7 +434,6 @@ void tcg_exec_unrealizefn(CPUState *cpu);
  static inline void cpu_set_cpustate_pointers(ArchCPU *cpu)
  {
  cpu->parent_obj.env_ptr = >env;
-cpu->parent_obj.icount_decr_ptr = >parent_obj.neg.icount_decr;
  }
  
  /* Validate correct placement of CPUArchState. */

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 1f289136ec..44955af3bc 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -440,7 +440,6 @@ struct qemu_work_item;
   * @as: Pointer to the first AddressSpace, for the convenience of targets 
which
   *  only have a single AddressSpace
   * @env_ptr: Pointer to subclass-specific CPUArchState field.
- * @icount_decr_ptr: Pointer to IcountDecr field within subclass.
   * @gdb_regs: Additional GDB registers.
   * @gdb_num_regs: Number of total registers accessible to GDB.
   * @gdb_num_g_regs: Number of registers in GDB 'g' packets.
@@ -512,7 +511,6 @@ struct CPUState {
  MemoryRegion *memory;
  
  CPUArchState *env_ptr;

-IcountDecr *icount_decr_ptr;
  
  CPUJumpCache *tb_jmp_cache;
  
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c

index ced66c2b34..08d5bbc873 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -86,7 +86,7 @@ void cpu_exit(CPUState *cpu)
  qatomic_set(>exit_request, 1);
  /* Ensure cpu_exec will see the exit request after TCG has exited.  */
  smp_wmb();
-qatomic_set(>icount_decr_ptr->u16.high, -1);
+qatomic_set(>neg.icount_decr.u16.high, -1);
  }
  
  static int cpu_common_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)

@@ -130,7 +130,7 @@ static void cpu_common_reset_hold(Object *obj)
  cpu->halted = cpu->start_powered_off;
  cpu->mem_io_pc = 0;
  cpu->icount_extra = 0;
-qatomic_set(>icount_decr_ptr->u32, 0);
+qatomic_set(>neg.icount_decr.u32, 0);
  cpu->can_do_io = 1;
  cpu->exception_index = -1;
  cpu->crash_occurred = false;

Reviewed-by: Anton Johansson 



Re: [PATCH v2 15/24] accel/tcg: Remove env_neg()

2023-09-14 Thread Anton Johansson via



On 9/14/23 04:44, Richard Henderson wrote:

Replace the single use within env_tlb() and remove.

Signed-off-by: Richard Henderson 
---
  include/exec/cpu-all.h | 13 +
  1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 9db8544125..af9516654a 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -451,17 +451,6 @@ static inline CPUState *env_cpu(CPUArchState *env)
  return (void *)env - sizeof(CPUState);
  }
  
-/**

- * env_neg(env)
- * @env: The architecture environment
- *
- * Return the CPUNegativeOffsetState associated with the environment.
- */
-static inline CPUNegativeOffsetState *env_neg(CPUArchState *env)
-{
-return (void *)env - sizeof(CPUNegativeOffsetState);
-}
-
  /**
   * env_tlb(env)
   * @env: The architecture environment
@@ -470,7 +459,7 @@ static inline CPUNegativeOffsetState *env_neg(CPUArchState 
*env)
   */
  static inline CPUTLB *env_tlb(CPUArchState *env)
  {
-return _neg(env)->tlb;
+return _cpu(env)->neg.tlb;
  }
  
  #endif /* CPU_ALL_H */

Reviewed-by: Anton Johansson 



Re: [PATCH v2 16/24] tcg: Remove TCGContext.tlb_fast_offset

2023-09-14 Thread Anton Johansson via



On 9/14/23 04:44, Richard Henderson wrote:

Now that there is no padding between CPUNegativeOffsetState
and CPUArchState, this value is constant across all targets.

Signed-off-by: Richard Henderson 
---
  include/tcg/tcg.h |  1 -
  accel/tcg/translate-all.c |  2 --
  tcg/tcg.c | 13 +++--
  3 files changed, 7 insertions(+), 9 deletions(-)

Reviewed-by: Anton Johansson 



Re: [PATCH v2 13/24] accel/tcg: Replace CPUState.env_ptr with cpu_env()

2023-09-14 Thread Anton Johansson via



On 9/14/23 04:44, Richard Henderson wrote:

Signed-off-by: Richard Henderson 
---
  include/exec/cpu-all.h   |  1 -
  include/hw/core/cpu.h|  9 ++---
  target/arm/common-semi-target.h  |  2 +-
  accel/tcg/cpu-exec.c |  8 
  accel/tcg/cputlb.c   | 18 +-
  accel/tcg/translate-all.c|  4 ++--
  gdbstub/gdbstub.c|  4 ++--
  gdbstub/user-target.c|  2 +-
  hw/i386/kvm/clock.c  |  2 +-
  hw/intc/mips_gic.c   |  2 +-
  hw/intc/riscv_aclint.c   | 12 ++--
  hw/intc/riscv_imsic.c|  2 +-
  hw/ppc/e500.c|  4 ++--
  hw/ppc/spapr.c   |  2 +-
  linux-user/elfload.c |  4 ++--
  linux-user/i386/cpu_loop.c   |  2 +-
  linux-user/main.c|  4 ++--
  linux-user/signal.c  | 15 +++
  monitor/hmp-cmds-target.c|  2 +-
  semihosting/arm-compat-semi.c|  6 +++---
  semihosting/syscalls.c   | 28 ++--
  target/alpha/translate.c |  4 ++--
  target/arm/cpu.c |  8 
  target/arm/helper.c  |  2 +-
  target/arm/tcg/translate-a64.c   |  4 ++--
  target/arm/tcg/translate.c   |  6 +++---
  target/avr/translate.c   |  2 +-
  target/cris/translate.c  |  4 ++--
  target/hexagon/translate.c   |  4 ++--
  target/hppa/mem_helper.c |  2 +-
  target/hppa/translate.c  |  4 ++--
  target/i386/tcg/sysemu/excp_helper.c |  2 +-
  target/i386/tcg/tcg-cpu.c|  2 +-
  target/i386/tcg/translate.c  |  4 ++--
  target/loongarch/translate.c |  4 ++--
  target/m68k/translate.c  |  4 ++--
  target/microblaze/translate.c|  2 +-
  target/mips/tcg/sysemu/mips-semi.c   |  4 ++--
  target/mips/tcg/translate.c  |  4 ++--
  target/nios2/translate.c |  4 ++--
  target/openrisc/translate.c  |  2 +-
  target/ppc/excp_helper.c | 10 +-
  target/ppc/translate.c   |  4 ++--
  target/riscv/translate.c |  6 +++---
  target/rx/cpu.c  |  3 ---
  target/rx/translate.c|  2 +-
  target/s390x/tcg/translate.c |  2 +-
  target/sh4/op_helper.c   |  2 +-
  target/sh4/translate.c   |  4 ++--
  target/sparc/translate.c |  4 ++--
  target/tricore/translate.c   |  4 ++--
  target/xtensa/translate.c|  4 ++--
  target/i386/tcg/decode-new.c.inc |  2 +-
  53 files changed, 125 insertions(+), 127 deletions(-)

Reviewed-by: Anton Johansson 



Re: [PATCH v2 08/24] accel/tcg: Move CPUNegativeOffsetState into CPUState

2023-09-14 Thread Anton Johansson via



On 9/14/23 04:44, Richard Henderson wrote:

Retain the separate structure to emphasize its importance.
Enforce CPUArchState always follows CPUState without padding.

Signed-off-by: Richard Henderson 
---
  include/exec/cpu-all.h| 22 +-
  include/hw/core/cpu.h | 14 --
  target/alpha/cpu.h|  1 -
  target/arm/cpu.h  |  1 -
  target/avr/cpu.h  |  1 -
  target/cris/cpu.h |  1 -
  target/hexagon/cpu.h  |  2 +-
  target/hppa/cpu.h |  1 -
  target/i386/cpu.h |  1 -
  target/loongarch/cpu.h|  1 -
  target/m68k/cpu.h |  1 -
  target/microblaze/cpu.h   |  6 +++---
  target/mips/cpu.h |  4 ++--
  target/nios2/cpu.h|  1 -
  target/openrisc/cpu.h |  1 -
  target/ppc/cpu.h  |  1 -
  target/riscv/cpu.h|  2 +-
  target/rx/cpu.h   |  1 -
  target/s390x/cpu.h|  1 -
  target/sh4/cpu.h  |  1 -
  target/sparc/cpu.h|  1 -
  target/tricore/cpu.h  |  1 -
  target/xtensa/cpu.h   |  3 +--
  accel/tcg/translate-all.c |  4 ++--
  accel/tcg/translator.c|  8 
  25 files changed, 35 insertions(+), 46 deletions(-)


Reviewed-by: Anton Johansson 



Re: [PATCH v2 22/24] accel/tcg: Remove env_tlb()

2023-09-14 Thread Anton Johansson via



On 9/14/23 17:44, Philippe Mathieu-Daudé wrote:

On 14/9/23 04:44, Richard Henderson wrote:

From: Anton Johansson 

The function is no longer used to access the TLB,
and has been replaced by cpu->neg.tlb.

Signed-off-by: Anton Johansson 
Message-Id: <20230912153428.17816-9-a...@rev.ng>
Reviewed-by: Richard Henderson 
[rth: Merge comment update patch]
Signed-off-by: Richard Henderson 
---
  include/exec/cpu-all.h   | 11 ---
  tcg/aarch64/tcg-target.c.inc |  2 +-
  tcg/arm/tcg-target.c.inc |  2 +-
  3 files changed, 2 insertions(+), 13 deletions(-)


Missing:

-- >8 --
diff --cc accel/tcg/cputlb.c
index bb7dcb87af,08df68f03a..00
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@@ -1746,7 -1734,7 +1734,7 @@@ bool tlb_plugin_lookup(CPUState *cpu, v
  /* We must have an iotlb entry for MMIO */
  if (tlb_addr & TLB_MMIO) {
  CPUTLBEntryFull *full;
- full = _tlb(env)->d[mmu_idx].fulltlb[index];
++    full = >neg.tlb.d[mmu_idx].fulltlb[index];
  data->is_io = true;
  data->v.io.section =
  iotlb_to_section(cpu, full->xlat_section, full->attrs);
---

(Noticed using --enable-plugins).

Ah right, I'll make sure to test with plugins in the future! Thanks:)

--
Anton Johansson,
rev.ng Labs Srl.




Re: [RFC PATCH v3 37/78] target/hexagon: add fallthrough pseudo-keyword

2023-10-16 Thread Anton Johansson via
On 13/10/23, Emmanouil Pitsidianakis wrote:
> In preparation of raising -Wimplicit-fallthrough to 5, replace all
> fall-through comments with the fallthrough attribute pseudo-keyword.
> 
> Signed-off-by: Emmanouil Pitsidianakis 
> ---
>  target/hexagon/idef-parser/parser-helpers.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

Reviewed-by: Anton Johansson 



Re: [PATCH 0/3] Hexagon (target/hexagon) Enable more short-circuit packets

2023-11-02 Thread Anton Johansson via
Hi, Taylor!:) Always nice to see your name pop up here. The patches seem 
to have been sent as attachments for whatever reason.

/ Anton



Re: [PATCH 0/9] Replace remaining target_ulong in system-mode accel

2023-09-22 Thread Anton Johansson via
On 21/09/23, Michael Tokarev wrote:
> 07.08.2023 18:56, Anton Johansson via wrote:
> > This patchset replaces the remaining uses of target_ulong in the accel/
> > directory.  Specifically, the address type of a few kvm/hvf functions
> > is widened to vaddr, and the address type of the cpu_[st|ld]*()
> > functions is changed to abi_ptr (which is re-typedef'd to vaddr in
> > system mode).
> > 
> > As a starting point, my goal is to be able to build cputlb.c once for
> > system mode, and this is a step in that direction by reducing the
> > target-dependence of accel/.
> > 
> > * Changes in v2:
> >  - Removed explicit target_ulong casts from 3rd and 4th patches.
> > 
> > Anton Johansson (9):
> >accel/kvm: Widen pc/saved_insn for kvm_sw_breakpoint
> >accel/hvf: Widen pc/saved_insn for hvf_sw_breakpoint
> >target: Use vaddr for kvm_arch_[insert|remove]_hw_breakpoint
> >target: Use vaddr for hvf_arch_[insert|remove]_hw_breakpoint
> >Replace target_ulong with abi_ptr in cpu_[st|ld]*()
> >include/exec: typedef abi_ptr to vaddr in softmmu
> >include/exec: Widen tlb_hit/tlb_hit_page()
> >accel/tcg: Widen address arg. in tlb_compare_set()
> >accel/tcg: Update run_on_cpu_data static assert
> 
> Pinging a relatively old patchset, - which fixes from here needs to
> go to stable-8.1?
> 
> The context: 
> https://lore.kernel.org/qemu-devel/20230721205827.7502-1-a...@rev.ng/
> And according to this email:
> 
> https://lore.kernel.org/qemu-devel/00e9e08eae1004ef67fe8dca3aaf5043e6863faa.ca...@gmail.com/
> 
> at least "include/exec: Widen tlb_hit/tlb_hit_page()" should go to 8.1,
> something else?
> 
> Thanks,
> 
> /mjt

If the patch above is the only one needed to fix the segfault (haven't
tested myself), pulling it in isolation is fine as it doesn't depend on 
any of the other patches.

The rest of the patches can be delayed without issue.

-- 
Anton Johansson
rev.ng Labs Srl.



Re: [PATCH 0/3] accel: Factor tcg_cpu_reset_hold() out of cpu-common.c

2023-09-18 Thread Anton Johansson via
On 18/09/23, Philippe Mathieu-Daudé wrote:
> Hi,
> 
> We want to have exec/ code agnostic to accelerators.
> still we use various call to TCG and KVM. This series
> factor the TCG code from cpu_common_reset_hold() to an
> accel-specific handler within AccelOpsClass.
> 
> Based-on: <20230915190009.68404-1-phi...@linaro.org>
> 
> Philippe Mathieu-Daudé (3):
>   accel/tcg: Declare tcg_flush_jmp_cache() in 'exec/tb-flush.h'
>   accel: Introduce cpu_exec_reset_hold()
>   accel/tcg: Factor tcg_cpu_reset_hold() out
> 
>  include/exec/cpu-common.h  | 3 ---
>  include/exec/tb-flush.h| 2 ++
>  include/hw/core/cpu.h  | 1 +
>  include/sysemu/accel-ops.h | 1 +
>  accel/stubs/tcg-stub.c | 4 
>  accel/tcg/cputlb.c | 1 +
>  accel/tcg/tcg-accel-ops.c  | 9 +
>  accel/tcg/translate-all.c  | 8 
>  accel/tcg/user-exec-stub.c | 4 
>  hw/core/cpu-common.c   | 5 +
>  plugins/core.c | 1 -
>  softmmu/cpus.c | 7 +++
>  12 files changed, 26 insertions(+), 20 deletions(-)
> 
> -- 
> 2.41.0
> 
Series:
Reviewed-by: Anton Johansson 



Re: [PATCH 0/2] Fix usage of GETPC(), variable shadowing

2023-10-04 Thread Anton Johansson via
On 04/10/23, Brian Cain wrote:
> Matheus' patch has previously been reviewed, but I based my -Wshadow
> patch on his.  So I'm submitting the series for review.
> 
> Brian Cain (1):
>   target/hexagon: fix some occurrences of -Wshadow=local
> 
> Matheus Tavares Bernardino (1):
>   target/hexagon: move GETPC() calls to top level helpers
> 
>  target/hexagon/imported/alu.idef |  6 +--
>  target/hexagon/macros.h  | 19 
>  target/hexagon/mmvec/macros.h|  2 +-
>  target/hexagon/op_helper.c   | 84 
>  target/hexagon/op_helper.h   |  9 
>  target/hexagon/translate.c   | 10 ++--
>  6 files changed, 50 insertions(+), 80 deletions(-)
> 
> -- 
> 2.25.1
> 

Both patches:
Reviewed-by: Anton Johansson 
Tested-by: Anton Johansson 



Re: [PATCH 0/9] Replace remaining target_ulong in system-mode accel

2023-09-25 Thread Anton Johansson via
On 23/09/23, Michael Tokarev wrote:
> [Trimming Cc list]
> 
> 22.09.2023 13:45, Anton Johansson:
> > On 21/09/23, Michael Tokarev wrote:
> 
> > > > Anton Johansson (9):
> > > > accel/kvm: Widen pc/saved_insn for kvm_sw_breakpoint
> > > > accel/hvf: Widen pc/saved_insn for hvf_sw_breakpoint
> > > > target: Use vaddr for kvm_arch_[insert|remove]_hw_breakpoint
> > > > target: Use vaddr for hvf_arch_[insert|remove]_hw_breakpoint
> > > > Replace target_ulong with abi_ptr in cpu_[st|ld]*()
> > > > include/exec: typedef abi_ptr to vaddr in softmmu
> > > > include/exec: Widen tlb_hit/tlb_hit_page()
> > > > accel/tcg: Widen address arg. in tlb_compare_set()
> > > > accel/tcg: Update run_on_cpu_data static assert
> > > 
> > > Pinging a relatively old patchset, - which fixes from here needs to
> > > go to stable-8.1?
> ...
> > The rest of the patches can be delayed without issue.
> 
> Now I'm confused.  What do you mean "delayed"?
> Should the rest be picked up for 8.1.2 or 8.1.3 or maybe 8.1.4?
> 
> The whole series has been accepted/applied to master, I asked which
> changes should be picked up for stable-8.1, - there's no delay involved,
> it is either picked up or not, either needed in stable or not.
> 
> Yes, "Widen tlb_hit/tlb_hit_page()" fixes a known bug and I picked
> up that one, - unfortunately it missed 8.1.1 release.  The question
> is about the other changes in this patch set, - do they fix other
> similar, not yet discovered, bugs in other places, or not fixing
> anything? Or should we delay picking them up until a bug is reported? :)
> 
> Thank you for the changes and the reply!
> 
> /mjt

Oh I see what you mean now, thanks for the clarification!:) I'm not that 
used to think in terms of what patches end up in stable.

The other patches in this series are refactors to reduce 
target-dependence in accel/, and they do not fix any bugs directly. 
Eventually we'll need to pick them up for compiling cputlb.c once for 
system mode etc., or other patches that depend on the refactor, but they 
are not critical to get in due to fixing some bug, that's what I meant 
by "can be delayed without issue".

How do you usually deal with these types of refactor heavy changes? 
Picking asap vs delaying until absolutely needed?

Thanks again for the explanation, I hope this was of some help.

//Anton



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

2022-04-21 Thread Anton Johansson via






-Original Message-
From: Anton Johansson 
Sent: Thursday, April 21, 2022 6:51 AM
To: Taylor Simpson ; qemu-devel@nongnu.org
Cc: a...@rev.ng; Brian Cain ; Michael Lambert
; bab...@rev.ng; ni...@rev.ng;
richard.hender...@linaro.org
Subject: Re: [PATCH v8 10/12] target/hexagon: import parser for idef-parser


Here's an updated version of `gen_set_usr_field_If`

https://gitlab.com/AntonJohansson/qemu/-/blob/feature/idef-
parser/target/hexagon/genptr.c#L673

If this looks alright and we have your "reviewed-by" on this patch, I'll go
ahead and submit the new patchset! :)
/*
  * Note: Since this function might branch, `val` is
  * required to be a `tcg_temp_local`.
  */
void gen_set_usr_field_if(int field, TCGv val)
{
 /* Sets the USR field if `val` is non-zero */
 if (false && reg_field_info[field].width == 1) {

Remove the "false &&"

Otherwise
Reviewed-by: Taylor Simpson 


Ah ofc! Remnant of testing. Fixed.

I'll rebase and run the usual pre-submit tests once again.





 TCGv tmp = tcg_temp_new();
 tcg_gen_extract_tl(tmp, val, 0, reg_field_info[field].width);
 tcg_gen_shli_tl(tmp, tmp, reg_field_info[field].offset);
 tcg_gen_or_tl(hex_new_value[HEX_REG_USR],
   hex_new_value[HEX_REG_USR],
   tmp);
 tcg_temp_free(tmp);
 } else {
 TCGLabel *skip_label = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, val, 0, skip_label);
 gen_set_usr_field(field, val);
 gen_set_label(skip_label);
 }
}




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

2022-04-22 Thread Anton Johansson via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Richard Henderson 
Reviewed-by: Taylor Simpson 
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 294c88ace9..d6b62ff319 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -200,6 +200,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
@@ -207,6 +209,13 @@ 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 
+M: Anton Johansson 
+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.35.1




[PATCH v9 08/12] target/hexagon: import flex/bison to docker files

2022-04-22 Thread Anton Johansson via
This patch points `tests/lcitool/libvirt-ci` to an upstreamed commit of
`libvirt-ci` which includes flex and bison. The `lcitool/refresh` script
was then ran to update the the generated docker/cirrus files.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
---
 .gitlab-ci.d/cirrus/freebsd-12.vars   |  2 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars   |  2 +-
 .gitlab-ci.d/cirrus/macos-11.vars |  2 +-
 .gitlab-ci.d/windows.yml  |  2 ++
 tests/docker/dockerfiles/alpine.docker|  6 --
 tests/docker/dockerfiles/centos8.docker   |  7 ---
 tests/docker/dockerfiles/debian-amd64.docker  |  2 ++
 .../dockerfiles/debian-arm64-cross.docker |  6 --
 tests/docker/dockerfiles/debian-native.docker |  3 +++
 .../dockerfiles/debian-riscv64-cross.docker   |  3 +++
 .../dockerfiles/debian-s390x-cross.docker |  6 --
 .../dockerfiles/debian-tricore-cross.docker   |  1 +
 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|  5 +++--
 tests/docker/dockerfiles/opensuse-leap.docker |  5 +++--
 tests/docker/dockerfiles/ubuntu1804.docker|  4 +++-
 tests/docker/dockerfiles/ubuntu2004.docker|  5 +++--
 tests/lcitool/libvirt-ci  |  2 +-
 tests/lcitool/projects/qemu.yml   | 20 ++-
 22 files changed, 66 insertions(+), 29 deletions(-)

diff --git a/.gitlab-ci.d/cirrus/freebsd-12.vars 
b/.gitlab-ci.d/cirrus/freebsd-12.vars
index b4842271b2..0cfe18c67c 100644
--- a/.gitlab-ci.d/cirrus/freebsd-12.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-12.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='pkg'
 PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake 
gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server 
libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman 
pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx py38-sphinx_rtd_theme 
py38-virtualenv py38-yaml python3 rpm2cpio sdl2 sdl2_image snappy 
spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
+PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache 
cdrkit-genisoimage ctags curl cyrus-sasl dbus diffutils dtc flex gettext git 
glib gmake gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs 
libspice-server libssh libtasn1 libxml2 llvm lzo2 meson ncurses nettle ninja 
opencv perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx 
py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 
sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 
zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars 
b/.gitlab-ci.d/cirrus/freebsd-13.vars
index 546a82dd75..33c8856fd4 100644
--- a/.gitlab-ci.d/cirrus/freebsd-13.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-13.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='pkg'
 PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake 
gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server 
libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman 
pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx py38-sphinx_rtd_theme 
py38-virtualenv py38-yaml python3 rpm2cpio sdl2 sdl2_image snappy 
spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
+PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache 
cdrkit-genisoimage ctags curl cyrus-sasl dbus diffutils dtc flex gettext git 
glib gmake gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs 
libspice-server libssh libtasn1 libxml2 llvm lzo2 meson ncurses nettle ninja 
opencv perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx 
py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 
sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 
zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/macos-11.vars 
b/.gitlab-ci.d/cirrus/macos-11.vars
index cfe9181fd4..1c7366c810 100644
--- a/.gitlab-ci.d/cirrus/macos-11.vars
+++ b/.gitlab-ci.d/cirrus/macos-11.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='brew'
 PIP3='/usr/local/bin/pip3'
-PKGS='bash bc bzip2 capstone ccache ctags curl dbus diffutils dtc gcovr 
gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo libepoxy libffi 
libgcrypt 

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

2022-04-22 Thread Anton Johansson 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 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/gen_idef_parser_funcs.py | 128 ++
 target/hexagon/idef-parser/macros.inc   | 140 
 target/hexagon/idef-parser/prepare  |  24 
 target/hexagon/meson.build  |  17 +++
 4 files changed, 309 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..178648b287
--- /dev/null
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python3
+
+##
+##  Copyright(c) 2019-2022 rev.ng Labs Srl. 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.calculate_attribs()
+tagregs = hex_common.get_tagregs()
+tagimms = hex_common.get_tagimms()
+
+with open(sys.argv[3], '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 that saturate in a ternary expression
+if ( tag in {'S2_asr_r_r_sat', 'S2_asl_r_r_sat'} ) :
+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
+if ( tag in {'M7_wcmpyrw', 'M7_wcmpyrwc',
+ 'M7_wcmpyiw', 'M7_wcmpyiwc',
+ 'M7_wcmpyrw_rnd', 'M7_wcmpyrwc_rnd',
+ 'M7_wcmpyiw_rnd', 'M7_wcmpyiwc_rnd'} ) :
+continue
+## Skip interleave/deinterleave instructions
+if ( tag in {'S2_interleave', 'S2_deinterleave'} ) :
+continue
+## Skip instructions using bit reverse
+if ( tag in {'S2_brev', 'S2_brevp', 'S2_ct0', 'S2_ct1',
+ 'S2_ct0p', 'S2_ct1p', 'A4_tlbmatch'} ) :
+continue
+## Skip other unsupported instructions
+if ( tag == 'S2_cabacdecbin' or tag == 'A5_ACS' ) :
+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 = []
+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))
+
+ 

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

2022-04-22 Thread Anton Johansson 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. An option is also added to fully
disable the output of the idef-parser, which is useful for debugging
purposes.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 meson_options.txt   |  3 +
 target/hexagon/gen_helper_funcs.py  | 17 +-
 target/hexagon/gen_helper_protos.py | 17 +-
 target/hexagon/gen_tcg_funcs.py | 41 -
 target/hexagon/hex_common.py| 10 
 target/hexagon/meson.build  | 92 +++--
 6 files changed, 146 insertions(+), 34 deletions(-)

diff --git a/meson_options.txt b/meson_options.txt
index 52b11cead4..ae8f53b1fd 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -270,3 +270,6 @@ option('profiler', type: 'boolean', value: false,
description: 'profiler support')
 option('slirp_smbd', type : 'feature', value : 'auto',
description: 'use smbd (at path --smbd=*) in slirp networking')
+
+option('hexagon_idef_parser_enabled', type : 'boolean', value : true,
+   description: 'Whether idef-parser should be used to automatically 
generate TCG code for the Hexagon frontend')
diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index a446c45384..71d611283a 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -287,11 +287,24 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+is_idef_parser_enabled = len(sys.argv) > 6
+if is_idef_parser_enabled:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -308,6 +321,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 3b4e993fd1..74eff457a6 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -136,11 +136,24 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+is_idef_parser_enabled = len(sys.argv) > 6
+if is_idef_parser_enabled:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -158,6 +171,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 1fd9de95d5..4d12e192a7 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -610,7 +610,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, 

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

2022-04-22 Thread Anton Johansson via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code, to
correctly implement instruction semantics. "Helper" functions, in the
context of this patch, refers to functions which provide a manual TCG
implementation of certain features.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/genptr.c | 178 ++--
 target/hexagon/genptr.h |  17 +++-
 target/hexagon/macros.h |   9 ++
 3 files changed, 196 insertions(+), 8 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 8d1b3f6e2e..036d0cef2e 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -31,6 +31,12 @@
 #include "gen_tcg_hvx.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]);
@@ -403,18 +409,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,
@@ -427,8 +434,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,
@@ -441,8 +447,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,
@@ -647,5 +652,164 @@ static void vec_to_qvec(size_t size, intptr_t dstoff, 
intptr_t srcoff)
 tcg_temp_free_i64(mask);
 }
 
+void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[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_constant_tl(x);
+gen_set_usr_field(field, val);
+}
+
+/*
+ * Note: Since this function might branch, `val` is
+ * required to be a `tcg_temp_local`.
+ */
+void gen_set_usr_field_if(int field, TCGv val)
+{
+/* Sets the USR field if `val` is non-zero */
+if (reg_field_info[field].width == 1) {
+TCGv tmp = tcg_temp_new();
+tcg_gen_extract_tl(tmp, val, 0, reg_field_info[field].width);
+tcg_gen_shli_tl(tmp, tmp, reg_field_info[field].offset);
+tcg_gen_or_tl(hex_new_value[HEX_REG_USR],
+  hex_new_value[HEX_REG_USR],
+  tmp);
+tcg_temp_free(tmp);
+} else {
+TCGLabel *skip_label = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, val, 0, skip_label);
+gen_set_usr_field(field, val);
+gen_set_label(skip_label);
+}
+}
+
+void gen_write_new_pc(TCGv addr)
+{
+/* If there are multiple branches in a packet, ignore the second one */
+TCGv zero = tcg_constant_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);
+}
+
+void gen_sat_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_constant_tl((1 << (width - 1)) - 1);
+TCGv min_val = tcg_constant_tl(-(1 << (width - 1)));
+tcg_gen_smin_tl(dest, source, max_val);
+tcg_gen_smax_tl(dest, dest, min_val);
+}
+
+void gen_sat_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_sat_i32(dest, source, width);
+tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest);
+}
+
+void gen_satu_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_constant_tl((1 << width) - 1);
+TCGv zero = tcg_constant_tl(0);
+tcg_gen_movcond_tl(TCG_COND_GTU, dest, source, max_val, max_val, source);
+

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

2022-04-22 Thread Anton Johansson via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 tests/tcg/hexagon/Makefile.target  | 28 -
 tests/tcg/hexagon/crt.S| 14 +++
 tests/tcg/hexagon/test_abs.S   | 17 
 tests/tcg/hexagon/test_bitcnt.S| 40 +++
 tests/tcg/hexagon/test_bitsplit.S  | 22 ++
 tests/tcg/hexagon/test_call.S  | 64 ++
 tests/tcg/hexagon/test_clobber.S   | 29 ++
 tests/tcg/hexagon/test_cmp.S   | 31 +++
 tests/tcg/hexagon/test_dotnew.S| 38 ++
 tests/tcg/hexagon/test_ext.S   | 13 ++
 tests/tcg/hexagon/test_fibonacci.S | 30 ++
 tests/tcg/hexagon/test_hl.S| 16 
 tests/tcg/hexagon/test_hwloops.S   | 19 +
 tests/tcg/hexagon/test_jmp.S   | 22 ++
 tests/tcg/hexagon/test_lsr.S   | 36 +
 tests/tcg/hexagon/test_mpyi.S  | 17 
 tests/tcg/hexagon/test_packet.S| 29 ++
 tests/tcg/hexagon/test_reorder.S   | 33 +++
 tests/tcg/hexagon/test_round.S | 29 ++
 tests/tcg/hexagon/test_vavgw.S | 31 +++
 tests/tcg/hexagon/test_vcmpb.S | 30 ++
 tests/tcg/hexagon/test_vcmpw.S | 30 ++
 tests/tcg/hexagon/test_vlsrw.S | 20 ++
 tests/tcg/hexagon/test_vmaxh.S | 35 
 tests/tcg/hexagon/test_vminh.S | 35 
 tests/tcg/hexagon/test_vpmpyh.S| 28 +
 tests/tcg/hexagon/test_vspliceb.S  | 31 +++
 27 files changed, 766 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_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_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_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 23b9870534..44ffa1337d 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
@@ -43,6 +43,32 @@ HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 HEX_TESTS += overflow
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_call
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+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_packet
+HEX_TESTS += test_reorder
+HEX_TESTS += test_round
+HEX_TESTS += test_vavgw
+HEX_TESTS += test_vcmpb
+HEX_TESTS += test_vcmpw
+HEX_TESTS += test_vlsrw
+HEX_TESTS += test_vmaxh
+HEX_TESTS += test_vminh
+HEX_TESTS += test_vpmpyh
+HEX_TESTS += test_vspliceb
+
 TESTS += $(HEX_TESTS)
 
 # This test has to be compiled for the -mv67t target
diff --git a/tests/tcg/hexagon/crt.S b/tests/tcg/hexagon/crt.S
new file mode 100644
index 00..f9e6bc80f7
--- /dev/null
+++ b/tests/tcg/hexagon/crt.S
@@ -0,0 +1,14 @@
+#define SYS_exit_group 94
+
+.text
+.globl pass
+pass:
+r0 = #0
+r6 = #SYS_exit_group
+trap0(#1)
+
+.globl fail
+fail:
+r0 = #1
+r6 = #SYS_exit_group
+trap0(#1)
diff --git a/tests/tcg/hexagon/test_abs.S b/tests/tcg/hexagon/test_abs.S
new file mode 100644
index 00..d68aea6f64
--- /dev/null
+++ b/tests/tcg/hexagon/test_abs.S
@@ -0,0 +1,17 @@
+/* Purpose: test example, verify the soundness of the abs operation */
+
+.text
+.globl _start
+
+_start:
+{
+r1 = #-2
+r2 = #2
+}
+{
+  

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

2022-04-22 Thread Anton Johansson 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.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 d4fc92f7e9..e3e250fd4f 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -741,11 +741,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, , false) > 0) {
 HEX_DEBUG_PRINT_PKT();
 gen_start_packet(ctx, );
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, [i], );
 }
 gen_commit_packet(env, ctx, );
-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 a245172827..494471548e 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -53,6 +53,7 @@ typedef struct DisasContext {
 bool qreg_is_predicated[NUM_QREGS];
 int qreg_log_idx;
 bool pre_commit;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.35.1




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

2022-04-22 Thread Anton Johansson via
Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/idef-parser/idef-parser.y|  961 
 target/hexagon/idef-parser/parser-helpers.c | 2346 +++
 target/hexagon/idef-parser/parser-helpers.h |  372 +++
 target/hexagon/meson.build  |   25 +
 4 files changed, 3704 insertions(+)
 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..096cca2d17
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,961 @@
+%{
+/*
+ *  Copyright(c) 2019-2022 rev.ng Labs Srl. All Rights Reserved.
+ *
+ *  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 .
+ */
+
+#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;
+HexSignedness signedness;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token IN INAME VAR
+%token ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS ASL
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE PC NPC LPCFG
+%token CANCEL IDENTITY PART1 ROTL INSBITS SETBITS EXTRANGE
+%token CAST4_8U FAIL CARRY_FROM_ADD ADDSAT64 LSBNEW
+%token TYPE_SIZE_T TYPE_INT TYPE_SIGNED TYPE_UNSIGNED TYPE_LONG
+
+%token  REG IMM PRED
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement var var_decl var_type
+%type  FAIL
+%type  TYPE_SIGNED TYPE_UNSIGNED TYPE_INT TYPE_LONG TYPE_SIZE_T
+%type  if_stmt IF
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left '('
+%left ','
+%left '='
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left '?' ':'
+%left ANDL
+%left '|'
+%left '^' ANDOR
+%left '&'
+%left EQ NEQ
+%left '<' '>' LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left '-' '+'
+%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
+  {
+  EMIT_SIG(c, ")");
+  EMIT_HEAD(c, "{\n");
+  }
+  code
+  {
+  gen_inst_code(c, &@1);
+  }
+| error /* Recover gracefully after instruction compilation error 
*/
+  {
+  free_instruction(c);
+  }
+;
+
+arguments : '(' ')'
+  | '(' argument_list ')';
+
+argument_list : argument_decl ',' argument_list
+  | argument_decl
+  ;
+
+var : VAR
+  {
+  track_string(c, $1.var.name);
+  $$ = $1;
+  }
+;
+
+/*
+ * Here the integer types are defined from valid combinations of
+ * `signed`, `unsigned`, `int`, and `long` tokens. The `signed`
+ * and `unsigned` tokens are here assumed to always be placed
+ * first in the type declaration, which is not the case in
+ * normal C. Similarly, `int` is assumed to always be placed
+ * last in the type.
+ */
+type_int : TYPE_INT
+ | TYPE_SIGNED
+ | TYPE_SIGNED TYPE_INT;
+type_uint : TYPE_UNSIGNED
+  | TYPE_UNSIGNED TYPE_INT;
+type_ulonglong : TYPE_UNSIGNED TYPE_LONG TYPE_LONG
+   | TYPE_UNSIGNED TYPE_LONG TYPE_LONG TYPE_INT;
+
+/*
+ * Here the various valid int types defined above specify
+ * their `signedness` and `bit_width`. The LP64 convention
+ * is assumed where longs are 64-bit, long longs are then
+ * assumed to also be 64-bit.
+ */
+var_type : TYPE_SIZE_T
+   {
+  yyassert(c, &@1, $1.bit_width <= 64,
+   "Variables with size > 64-bit are 

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

2022-04-22 Thread Anton Johansson via
From: Alessandro Di Federico 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/README |   5 +
 target/hexagon/idef-parser/README.rst | 722 ++
 2 files changed, 727 insertions(+)
 create mode 100644 target/hexagon/idef-parser/README.rst

diff --git a/target/hexagon/README b/target/hexagon/README
index 372e24747c..6cb5affddb 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -27,6 +27,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
@@ -47,6 +51,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..65e6bf4ee5
--- /dev/null
+++ b/target/hexagon/idef-parser/README.rst
@@ -0,0 +1,722 @@
+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;} */
+   {
+   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 

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

2022-04-22 Thread Anton Johansson via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/idef-parser/idef-parser.h   | 253 +++
 target/hexagon/idef-parser/idef-parser.lex | 471 +
 target/hexagon/meson.build |   4 +
 3 files changed, 728 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..5c49d4da3e
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,253 @@
+/*
+ *  Copyright(c) 2019-2022 rev.ng Labs Srl. 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 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 } HexRegType;
+
+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   
*/
+HexRegType 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 {
+unsigned 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, used when type is VARIABLE   
*/
+uint64_t value; /**< Immediate value, used when type is VALUE 
*/
+uint64_t index; /**< Index, used when type is QEMU_TMP
*/
+};
+enum ImmUnionTag type;  /**< Type of the immediate
*/
+} HexImm;
+
+/**
+ * Semantic record of the PRED token, identifying a predicate
+ */
+typedef struct HexPred {
+char id;/**< Identifier of the predicate  
*/
+} HexPred;
+
+/**
+ * Semantic record of the SAT token, identifying the saturate operator
+ * Note: All saturates are assumed to implicitly set overflow.
+ */
+typedef struct HexSat {
+HexSignedness signedness;   /**< Signedness of the sat. op.   
*/
+} HexSat;
+
+/**
+ * Semantic record of the CAST token, identifying the cast operator
+ */
+typedef struct HexCast {
+unsigned bit_width; /**< Bit width of the cast operator   
*/
+HexSignedness signedness;   /**< Unsigned flag for the cast operator  
*/
+} HexCast;
+
+/**
+ * Semantic record of 

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

2022-04-22 Thread Anton Johansson via
This patchset introduces the idef-parser for target/hexagon.

It's the ninth 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 Pseudocode
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:

* These commits build successfully on the CI (including using clang),
  with one notable exception. Presently, the `build-user-hexagon` job
  fails due to not being able to find `flex`/`bison`. This is due to
  the `debian-hexagon-cross` container not being built by the CI.

  As such the `debian-hexagon-cross` container will have to be manually
  rebuilt before merging.

* `checkpatch.pl` complains about the `_Generic` macro `OUT_IMPL` in
  `idef-parser/parser-helpers.h` which we believe to be correctly
  formatted. The complaints concern the `:` in the type "labels" of the
  macro, and also the `default:` label.

* The eight patch, which introduces `flex`/`bison` as new build pre-
  requisites using `libvirt-ci`, will update `tests/lcitool/libvirt-ci`
  to a new upstream commit which includes these package mappings.

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

Anton Johansson (2):
  target/hexagon: import flex/bison to docker files
  target/hexagon: import parser for idef-parser

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

Paolo Montesel (4):
  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

 .gitlab-ci.d/cirrus/freebsd-12.vars   |2 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars   |2 +-
 .gitlab-ci.d/cirrus/macos-11.vars |2 +-
 .gitlab-ci.d/windows.yml  |2 +
 MAINTAINERS   |9 +
 meson_options.txt |3 +
 target/hexagon/README |5 +
 target/hexagon/gen_helper_funcs.py|   17 +-
 target/hexagon/gen_helper_protos.py   |   17 +-
 target/hexagon/gen_idef_parser_funcs.py   |  128 +
 target/hexagon/gen_tcg_funcs.py   |   41 +-
 target/hexagon/genptr.c   |  241 +-
 target/hexagon/genptr.h   |   45 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  722 +
 target/hexagon/idef-parser/idef-parser.h  |  253 ++
 target/hexagon/idef-parser/idef-parser.lex|  471 
 target/hexagon/idef-parser/idef-parser.y  |  961 +++
 target/hexagon/idef-parser/macros.inc |  140 +
 target/hexagon/idef-parser/parser-helpers.c   | 2346 +
 target/hexagon/idef-parser/parser-helpers.h   |  372 +++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/macros.h   |   11 +-
 target/hexagon/meson.build|  138 +-
 target/hexagon/op_helper.c|   29 +-
 target/hexagon/op_helper.h|   37 +
 target/hexagon/translate.c|3 +-
 target/hexagon/translate.h|1 +
 tests/docker/dockerfiles/alpine.docker|6 +-
 tests/docker/dockerfiles/centos8.docker   |7 +-
 tests/docker/dockerfiles/debian-amd64.docker  |2 +
 .../dockerfiles/debian-arm64-cross.docker |6 +-
 tests/docker/dockerfiles/debian-native.docker |3 +
 .../dockerfiles/debian-riscv64-cross.docker   |3 +
 .../dockerfiles/debian-s390x-cross.docker |6 +-
 .../dockerfiles/debian-tricore-cross.docker   |1 +
 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|5 +-
 tests/docker/dockerfiles/opensuse-leap.docker |5 +-
 tests/docker/dockerfiles/ubuntu1804.docker|4 +-
 tests/docker/dockerfiles/ubuntu2004.docker|5 +-
 tests/lcitool/libvirt-ci  |2 +-
 tests/lcitool/projects/qemu.yml   |   20 +-
 tests/tcg/hexagon/Makefile.target |   28 +-
 tests/tcg/hexagon/crt.S   |   14 +
 tests/tcg/hexagon/test_abs.S  |   17 +
 tests/tcg/hexagon/test_bitcnt.S   |   40 +
 

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

2022-04-22 Thread Anton Johansson via
From: Paolo Montesel 

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

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index cd6af4bceb..df126de55b 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -30,7 +30,8 @@
 #include "gen_tcg.h"
 #include "gen_tcg_hvx.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_constant_tl(0);
 TCGv slot_mask = tcg_temp_new();
@@ -62,7 +63,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_constant_tl(0);
@@ -394,7 +396,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);
@@ -402,49 +404,49 @@ 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_constant_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store2(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store4(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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);
@@ -453,7 +455,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_constant_i64(src);
 gen_store8(cpu_env, vaddr, tmp, ctx, slot);
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index a78e84faa4..5ea2d54ebe 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_temp_new();
 TCGv tmp = tcg_temp_new();
-- 
2.35.1




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

2022-04-22 Thread Anton Johansson 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.c| 59 +-
 target/hexagon/genptr.h| 30 +++
 target/hexagon/op_helper.c | 29 +--
 target/hexagon/op_helper.h | 37 
 4 files changed, 113 insertions(+), 42 deletions(-)
 create mode 100644 target/hexagon/op_helper.h

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index df126de55b..8d1b3f6e2e 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -29,6 +29,13 @@
 #undef QEMU_GENERATE
 #include "gen_tcg.h"
 #include "gen_tcg_hvx.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)
@@ -54,7 +61,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) {
@@ -116,7 +123,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 base_val = tcg_temp_new();
 
@@ -274,7 +281,7 @@ static inline void gen_write_ctrl_reg_pair(DisasContext 
*ctx, int reg_num,
 }
 }
 
-static TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign)
+TCGv gen_get_byte(TCGv result, int N, TCGv src, bool sign)
 {
 if (sign) {
 tcg_gen_sextract_tl(result, src, N * 8, 8);
@@ -284,7 +291,7 @@ static TCGv gen_get_byte(TCGv result, int N, TCGv src, bool 
sign)
 return result;
 }
 
-static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign)
+TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 src, bool sign)
 {
 TCGv_i64 res64 = tcg_temp_new_i64();
 if (sign) {
@@ -298,7 +305,7 @@ static TCGv gen_get_byte_i64(TCGv result, int N, TCGv_i64 
src, bool sign)
 return result;
 }
 
-static inline TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign)
+TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign)
 {
 if (sign) {
 tcg_gen_sextract_tl(result, src, N * 16, 16);
@@ -308,12 +315,12 @@ static inline TCGv gen_get_half(TCGv result, int N, TCGv 
src, bool sign)
 return result;
 }
 
-static inline void gen_set_half(int N, TCGv result, TCGv src)
+void gen_set_half(int N, TCGv result, TCGv src)
 {
 tcg_gen_deposit_tl(result, result, src, N * 16, 16);
 }
 
-static inline void gen_set_half_i64(int N, TCGv_i64 result, TCGv src)
+void gen_set_half_i64(int N, TCGv_i64 result, TCGv src)
 {
 TCGv_i64 src64 = tcg_temp_new_i64();
 tcg_gen_extu_i32_i64(src64, src);
@@ -321,7 +328,7 @@ static inline void gen_set_half_i64(int N, TCGv_i64 result, 
TCGv src)
 tcg_temp_free_i64(src64);
 }
 
-static void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
+void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
 {
 TCGv_i64 src64 = tcg_temp_new_i64();
 tcg_gen_extu_i32_i64(src64, src);
@@ -396,57 +403,57 @@ 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, uint32_t slot)
+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);
 tcg_gen_mov_tl(hex_store_val32[slot], src);
 }
 
-static inline void gen_store1(TCGv_env cpu_env, TCGv vaddr, TCGv src,
-  DisasContext *ctx, uint32_t slot)
+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;
 }
 
-static inline void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src,
-   DisasContext *ctx, uint32_t slot)
+void gen_store1i(TCGv_env cpu_env, TCGv vaddr, int32_t src, DisasContext *ctx,
+ uint32_t slot)
 {
 TCGv tmp = tcg_constant_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
 }
 
-static inline void gen_store2(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,
+  

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

2022-04-21 Thread Anton Johansson via

Here's an updated version of `gen_set_usr_field_If`

https://gitlab.com/AntonJohansson/qemu/-/blob/feature/idef-parser/target/hexagon/genptr.c#L673

If this looks alright and we have your "reviewed-by" on this patch, I'll 
go ahead and submit the new

patchset! :)

--
Anton Johansson,
rev.ng Labs Srl.




From: Anton Johansson 
Sent: Tuesday, April 12, 2022 10:11 AM
To: Taylor Simpson ; qemu-devel@nongnu.org
Cc: a...@rev.ng; Brian Cain ; Michael Lambert 
; bab...@rev.ng; ni...@rev.ng; richard.hender...@linaro.org
Subject: Re: [PATCH v8 10/12] target/hexagon: import parser for idef-parser

Very nice catch, this is the bug that plagued us a few weeks ago when rebasing,
it has since been fixed. Actually the `gen_set_overflow` fucntion has been 
removed
completely as it was only called when we handled `asl/asr_r_r_sat`.
Current way we handle overflow:

Overflow is now only set by saturates, this assumption holds for the 
instructions
we parse in phase 1. In the parser, all saturates call `gen_rvalue_sat` which 
emits
a call to `gen_set_usr_field_if` in `genptr.c` to set USR_OVF only if the value 
is
non-zero. It does this via OR'ing with the previous value.

See 
https://gitlab.com/AntonJohansson/qemu/-/blob/feature/idef-parser/target/hexagon/idef-parser/parser-helpers.c#L2109
 for `gen_rvalue_sat`
and 
https://gitlab.com/AntonJohansson/qemu/-/blob/feature/idef-parser/target/hexagon/genptr.c#L669
 for `gen_set_usr_field_if`

Your implementation of gen_set_usr_field_if is not correct.  Don't extract the bits from the value 
based on the reg_field_info.  The easiest thing to do is compare val with zero and jump over a call 
to gen_set_usr_field.  If you are determined to do an "or", you have to assert that 
ref_field_info[field].width == 1.  Then, you can extract 1 bit from val starting at offset zero and 
shift the result left by ref_field_info[field].offset and then "or" with USR.

Thanks,
Taylor





Re: [PATCH v9 08/12] target/hexagon: import flex/bison to docker files

2022-05-25 Thread Anton Johansson via

On 5/25/22 18:38, Alex Bennée wrote:


Richard Henderson  writes:


On 5/25/22 05:29, Anton Johansson wrote:

For clarity's sake, here are the exact steps taken to produce this patch:
      1. Update QEMU's libvirt-ci to the commit
https://gitlab.com/libvirt/libvirt-ci/-/commit/43927ff508e8ecb1ac225dabbc95b37c890db917
     which adds flex/bison, and a native glib2 (required since
idef-parser
     is a build-time tool.)

This must be split out -- submodule updates should be a patch by
themselves.  Otherwise it can look like unintentional rebase breakage
(which, sadly, happens more often than legitimate submodule updates).


      2. Copy in new `tests/lcitool/projects/qemu.yml` from `libvirt-ci`
      3. run `tests/lcitool/refresh` to generate new docker/cirrus
files

And, yes, having one patch that's simply auto-generated is helpful.

To quote danpb:

danpb: should our tests/lcitool/projects/qemu.yml match the one in
   the lcitool repo or are they different use cases?
the one in libvirt-ci.git should be deleted really
the one in qemu.git is the source of truth

so please just update the qemu.git qemu.yml for just what you need for
flex/bison without bringing in all the other (stale?) stuff.




r~



I see, thanks!

Just to make sure I understood you correctly, I should:

    1. Make a standalone patch that updates libvirt-ci and runs
    the refresh script, in case any package mappings changed

    2. Change this patch to add flex/bison to QEMU's qemu.yml,
    and run refresh

--
Anton Johansson,
rev.ng Labs Srl.




Re: [PATCH v9 08/12] target/hexagon: import flex/bison to docker files

2022-05-25 Thread Anton Johansson via

On 5/25/22 22:16, Richard Henderson wrote:



No:

* one patch to update libvirt-ci and does nothing else.
* one patch to update yml template.
* one patch to refresh.

Just like you enumerated before.


r~

Ah, right! Thanks for clarifying. Should I keep all 3 patches in this 
series?


--
Anton Johansson,
rev.ng Labs Srl.




[PATCH v10 00/16] target/hexagon: introduce idef-parser

2022-06-01 Thread Anton Johansson via
This patchset introduces the idef-parser for target/hexagon.

It's the tenth 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 Pseudocode
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:

* These commits build successfully on the CI (including using clang),
  with one notable exception. Presently, the build-user-hexagon job
  fails due to not being able to find flex/bison. This is due to
  the debian-hexagon-cross container not being built by the CI.

  As such the debian-hexagon-cross container will have to be manually
  rebuilt before merging.

* checkpatch.pl complains about the _Generic macro OUT_IMPL in
  idef-parser/parser-helpers.h which we believe to be correctly
  formatted. The complaints concern the `:` in the type "labels" of the
  macro, and also the `default:` label.

* Patches 8-12 (inclusive) introduce flex, bison, and a native glib2 to
  the CI containers, in the following steps:

1. Update libvirt-ci to a commit which includes
   flex and bison mappings

2. Fix renamed package mappings

3. Add flex, bison, and glib2 to qemu.yml

4. Regenerate docker/cirrus files using the refresh
   script

5. Manually add flex, bison, and glib2 to remaining
   containers which build qemu-hexagon but are not
   covered by libvirt-ci

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

Anton Johansson (6):
  target/hexagon: update libvirt-ci submodule
  target/hexagon: fix renamed package templates
  target/hexagon: add flex/bison/glib2 to qemu.yml
  target/hexagon: regenerate docker/cirrus files
  target/hexagon: manually add flex/bison/glib2 to remaining containers
  target/hexagon: import parser for idef-parser

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

Paolo Montesel (4):
  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

 .gitlab-ci.d/cirrus/freebsd-12.vars   |2 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars   |2 +-
 .gitlab-ci.d/cirrus/macos-11.vars |2 +-
 .gitlab-ci.d/windows.yml  |6 +-
 MAINTAINERS   |9 +
 meson_options.txt |3 +
 target/hexagon/README |5 +
 target/hexagon/gen_helper_funcs.py|   17 +-
 target/hexagon/gen_helper_protos.py   |   17 +-
 target/hexagon/gen_idef_parser_funcs.py   |  128 +
 target/hexagon/gen_tcg_funcs.py   |   41 +-
 target/hexagon/genptr.c   |  241 +-
 target/hexagon/genptr.h   |   45 +
 target/hexagon/hex_common.py  |   10 +
 target/hexagon/idef-parser/README.rst |  722 +
 target/hexagon/idef-parser/idef-parser.h  |  253 ++
 target/hexagon/idef-parser/idef-parser.lex|  471 
 target/hexagon/idef-parser/idef-parser.y  |  961 +++
 target/hexagon/idef-parser/macros.inc |  140 +
 target/hexagon/idef-parser/parser-helpers.c   | 2346 +
 target/hexagon/idef-parser/parser-helpers.h   |  372 +++
 target/hexagon/idef-parser/prepare|   24 +
 target/hexagon/macros.h   |   11 +-
 target/hexagon/meson.build|  138 +-
 target/hexagon/op_helper.c|   29 +-
 target/hexagon/op_helper.h|   37 +
 target/hexagon/translate.c|3 +-
 target/hexagon/translate.h|1 +
 tests/docker/dockerfiles/alpine.docker|3 +
 tests/docker/dockerfiles/centos8.docker   |4 +-
 .../dockerfiles/debian-arm64-cross.docker |3 +
 .../dockerfiles/debian-riscv64-cross.docker   |3 +
 .../dockerfiles/debian-s390x-cross.docker |3 +
 .../dockerfiles/debian-tricore-cross.docker   |1 +
 tests/docker/dockerfiles/debian10.docker  |3 +
 .../dockerfiles/fedora-i386-cross.docker  |2 +
 .../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/ubuntu2004.docker|2 +
 tests/lcitool/libvirt-ci  

[PATCH v10 14/16] target/hexagon: import parser for idef-parser

2022-06-01 Thread Anton Johansson via
Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/idef-parser/idef-parser.y|  961 
 target/hexagon/idef-parser/parser-helpers.c | 2346 +++
 target/hexagon/idef-parser/parser-helpers.h |  372 +++
 target/hexagon/meson.build  |   25 +
 4 files changed, 3704 insertions(+)
 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..096cca2d17
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -0,0 +1,961 @@
+%{
+/*
+ *  Copyright(c) 2019-2022 rev.ng Labs Srl. All Rights Reserved.
+ *
+ *  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 .
+ */
+
+#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;
+HexSignedness signedness;
+int index;
+}
+
+/* Tokens */
+%start input
+
+%expect 1
+
+%token IN INAME VAR
+%token ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS ASL
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE PC NPC LPCFG
+%token CANCEL IDENTITY PART1 ROTL INSBITS SETBITS EXTRANGE
+%token CAST4_8U FAIL CARRY_FROM_ADD ADDSAT64 LSBNEW
+%token TYPE_SIZE_T TYPE_INT TYPE_SIGNED TYPE_UNSIGNED TYPE_LONG
+
+%token  REG IMM PRED
+%token  ELSE
+%token  MPY
+%token  SAT
+%token  CAST DEPOSIT SETHALF
+%token  EXTRACT
+%type  INAME
+%type  rvalue lvalue VAR assign_statement var var_decl var_type
+%type  FAIL
+%type  TYPE_SIGNED TYPE_UNSIGNED TYPE_INT TYPE_LONG TYPE_SIZE_T
+%type  if_stmt IF
+%type  SIGN
+
+/* Operator Precedences */
+%left MIN MAX
+%left '('
+%left ','
+%left '='
+%right CIRCADD
+%right INC DEC ANDA ORA XORA
+%left '?' ':'
+%left ANDL
+%left '|'
+%left '^' ANDOR
+%left '&'
+%left EQ NEQ
+%left '<' '>' LTE GTE
+%left ASL ASR LSR
+%right ABS
+%left '-' '+'
+%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
+  {
+  EMIT_SIG(c, ")");
+  EMIT_HEAD(c, "{\n");
+  }
+  code
+  {
+  gen_inst_code(c, &@1);
+  }
+| error /* Recover gracefully after instruction compilation error 
*/
+  {
+  free_instruction(c);
+  }
+;
+
+arguments : '(' ')'
+  | '(' argument_list ')';
+
+argument_list : argument_decl ',' argument_list
+  | argument_decl
+  ;
+
+var : VAR
+  {
+  track_string(c, $1.var.name);
+  $$ = $1;
+  }
+;
+
+/*
+ * Here the integer types are defined from valid combinations of
+ * `signed`, `unsigned`, `int`, and `long` tokens. The `signed`
+ * and `unsigned` tokens are here assumed to always be placed
+ * first in the type declaration, which is not the case in
+ * normal C. Similarly, `int` is assumed to always be placed
+ * last in the type.
+ */
+type_int : TYPE_INT
+ | TYPE_SIGNED
+ | TYPE_SIGNED TYPE_INT;
+type_uint : TYPE_UNSIGNED
+  | TYPE_UNSIGNED TYPE_INT;
+type_ulonglong : TYPE_UNSIGNED TYPE_LONG TYPE_LONG
+   | TYPE_UNSIGNED TYPE_LONG TYPE_LONG TYPE_INT;
+
+/*
+ * Here the various valid int types defined above specify
+ * their `signedness` and `bit_width`. The LP64 convention
+ * is assumed where longs are 64-bit, long longs are then
+ * assumed to also be 64-bit.
+ */
+var_type : TYPE_SIZE_T
+   {
+  yyassert(c, &@1, $1.bit_width <= 64,
+   "Variables with size > 64-bit are 

[PATCH v10 05/16] target/hexagon: introduce new helper functions

2022-06-01 Thread Anton Johansson via
From: Niccolò Izzo 

These helpers will be employed by the idef-parser generated code, to
correctly implement instruction semantics. "Helper" functions, in the
context of this patch, refers to functions which provide a manual TCG
implementation of certain features.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/genptr.c | 178 ++--
 target/hexagon/genptr.h |  17 +++-
 target/hexagon/macros.h |   9 ++
 3 files changed, 196 insertions(+), 8 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 8d1b3f6e2e..036d0cef2e 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -31,6 +31,12 @@
 #include "gen_tcg_hvx.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]);
@@ -403,18 +409,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,
@@ -427,8 +434,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,
@@ -441,8 +447,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,
@@ -647,5 +652,164 @@ static void vec_to_qvec(size_t size, intptr_t dstoff, 
intptr_t srcoff)
 tcg_temp_free_i64(mask);
 }
 
+void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[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_constant_tl(x);
+gen_set_usr_field(field, val);
+}
+
+/*
+ * Note: Since this function might branch, `val` is
+ * required to be a `tcg_temp_local`.
+ */
+void gen_set_usr_field_if(int field, TCGv val)
+{
+/* Sets the USR field if `val` is non-zero */
+if (reg_field_info[field].width == 1) {
+TCGv tmp = tcg_temp_new();
+tcg_gen_extract_tl(tmp, val, 0, reg_field_info[field].width);
+tcg_gen_shli_tl(tmp, tmp, reg_field_info[field].offset);
+tcg_gen_or_tl(hex_new_value[HEX_REG_USR],
+  hex_new_value[HEX_REG_USR],
+  tmp);
+tcg_temp_free(tmp);
+} else {
+TCGLabel *skip_label = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, val, 0, skip_label);
+gen_set_usr_field(field, val);
+gen_set_label(skip_label);
+}
+}
+
+void gen_write_new_pc(TCGv addr)
+{
+/* If there are multiple branches in a packet, ignore the second one */
+TCGv zero = tcg_constant_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);
+}
+
+void gen_sat_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_constant_tl((1 << (width - 1)) - 1);
+TCGv min_val = tcg_constant_tl(-(1 << (width - 1)));
+tcg_gen_smin_tl(dest, source, max_val);
+tcg_gen_smax_tl(dest, dest, min_val);
+}
+
+void gen_sat_i32_ovfl(TCGv ovfl, TCGv dest, TCGv source, int width)
+{
+gen_sat_i32(dest, source, width);
+tcg_gen_setcond_tl(TCG_COND_NE, ovfl, source, dest);
+}
+
+void gen_satu_i32(TCGv dest, TCGv source, int width)
+{
+TCGv max_val = tcg_constant_tl((1 << width) - 1);
+TCGv zero = tcg_constant_tl(0);
+tcg_gen_movcond_tl(TCG_COND_GTU, dest, source, max_val, max_val, source);
+

[PATCH v10 06/16] target/hexagon: expose next PC in DisasContext

2022-06-01 Thread Anton Johansson 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.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 d4fc92f7e9..e3e250fd4f 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -741,11 +741,12 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 if (decode_packet(nwords, words, , false) > 0) {
 HEX_DEBUG_PRINT_PKT();
 gen_start_packet(ctx, );
+ctx->npc = ctx->base.pc_next + pkt.encod_pkt_size_in_bytes;
 for (i = 0; i < pkt.num_insns; i++) {
 gen_insn(env, ctx, [i], );
 }
 gen_commit_packet(env, ctx, );
-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 a245172827..494471548e 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -53,6 +53,7 @@ typedef struct DisasContext {
 bool qreg_is_predicated[NUM_QREGS];
 int qreg_log_idx;
 bool pre_commit;
+uint32_t npc;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
-- 
2.36.1




[PATCH v10 11/16] target/hexagon: regenerate docker/cirrus files

2022-06-01 Thread Anton Johansson via
This patch updates the docker and cirrus files with the new packages by
running tests/lcitool/refresh

Signed-off-by: Anton Johansson 
---
 .gitlab-ci.d/cirrus/freebsd-12.vars| 2 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars| 2 +-
 .gitlab-ci.d/cirrus/macos-11.vars  | 2 +-
 tests/docker/dockerfiles/alpine.docker | 3 +++
 tests/docker/dockerfiles/centos8.docker| 4 +++-
 tests/docker/dockerfiles/debian-arm64-cross.docker | 3 +++
 tests/docker/dockerfiles/debian-s390x-cross.docker | 3 +++
 tests/docker/dockerfiles/fedora.docker | 2 ++
 tests/docker/dockerfiles/opensuse-leap.docker  | 2 ++
 tests/docker/dockerfiles/ubuntu2004.docker | 2 ++
 10 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/.gitlab-ci.d/cirrus/freebsd-12.vars 
b/.gitlab-ci.d/cirrus/freebsd-12.vars
index b4842271b2..616e65bc7f 100644
--- a/.gitlab-ci.d/cirrus/freebsd-12.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-12.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='pkg'
 PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake 
gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server 
libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman 
pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx py38-sphinx_rtd_theme 
py38-virtualenv py38-yaml python3 rpm2cpio sdl2 sdl2_image snappy 
spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
+PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache 
cdrkit-genisoimage ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 
gettext git glib gmake gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo 
libnfs libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja 
opencv perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx 
py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 
sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 
zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars 
b/.gitlab-ci.d/cirrus/freebsd-13.vars
index 546a82dd75..edabe3de1c 100644
--- a/.gitlab-ci.d/cirrus/freebsd-13.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-13.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='pkg'
 PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage 
ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake 
gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server 
libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman 
pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx py38-sphinx_rtd_theme 
py38-virtualenv py38-yaml python3 rpm2cpio sdl2 sdl2_image snappy 
spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
+PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache 
cdrkit-genisoimage ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 
gettext git glib gmake gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo 
libnfs libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja 
opencv perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx 
py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 
sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 
zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/macos-11.vars 
b/.gitlab-ci.d/cirrus/macos-11.vars
index cfe9181fd4..a0e4c77dbb 100644
--- a/.gitlab-ci.d/cirrus/macos-11.vars
+++ b/.gitlab-ci.d/cirrus/macos-11.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='brew'
 PIP3='/usr/local/bin/pip3'
-PKGS='bash bc bzip2 capstone ccache ctags curl dbus diffutils dtc gcovr 
gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo libepoxy libffi 
libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make 
meson ncurses nettle ninja perl pixman pkg-config python3 rpm2cpio sdl2 
sdl2_image snappy sparse spice-protocol tesseract texinfo usbredir vde vte3 
zlib zstd'
+PKGS='bash bc bison bzip2 capstone ccache ctags curl dbus diffutils dtc flex 
gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo libepoxy libffi 
libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make 
meson ncurses nettle ninja perl pixman pkg-config python3 rpm2cpio sdl2 
sdl2_image snappy sparse spice-protocol tesseract texinfo usbredir vde vte3 
zlib zstd'
 PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme virtualenv'
 PYTHON='/usr/local/bin/python3'
diff --git a/tests/docker/dockerfiles/alpine.docker 
b/tests/docker/dockerfiles/alpine.docker
index 

[PATCH v10 12/16] target/hexagon: manually add flex/bison/glib2 to remaining containers

2022-06-01 Thread Anton Johansson via
Adds our build-time dependencies to containers which build qemu-hexagon,
but aren't covered by libvirt-ci.

Signed-off-by: Anton Johansson 
---
 .gitlab-ci.d/windows.yml | 6 --
 tests/docker/dockerfiles/debian-riscv64-cross.docker | 3 +++
 tests/docker/dockerfiles/debian-tricore-cross.docker | 1 +
 tests/docker/dockerfiles/debian10.docker | 3 +++
 tests/docker/dockerfiles/fedora-i386-cross.docker| 2 ++
 tests/docker/dockerfiles/fedora-win32-cross.docker   | 3 +++
 tests/docker/dockerfiles/fedora-win64-cross.docker   | 3 +++
 7 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml
index cf7724b8e5..3777ec982b 100644
--- a/.gitlab-ci.d/windows.yml
+++ b/.gitlab-ci.d/windows.yml
@@ -32,7 +32,8 @@ msys2-64bit:
   extends: .shared_msys2_builder
   script:
   - .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
-  diffutils git grep make sed
+  bison diffutils flex
+  git grep make sed
   mingw-w64-x86_64-capstone
   mingw-w64-x86_64-curl
   mingw-w64-x86_64-cyrus-sasl
@@ -66,7 +67,8 @@ msys2-32bit:
   extends: .shared_msys2_builder
   script:
   - .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
-  diffutils git grep make sed
+  bison diffutils flex
+  git grep make sed
   mingw-w64-i686-capstone
   mingw-w64-i686-curl
   mingw-w64-i686-cyrus-sasl
diff --git a/tests/docker/dockerfiles/debian-riscv64-cross.docker 
b/tests/docker/dockerfiles/debian-riscv64-cross.docker
index 594d97982c..9715791e0b 100644
--- a/tests/docker/dockerfiles/debian-riscv64-cross.docker
+++ b/tests/docker/dockerfiles/debian-riscv64-cross.docker
@@ -16,13 +16,16 @@ RUN apt update && \

 # Install common build utilities
 RUN DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy \
+bison \
 bc \
 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 b573b9ded2..63f977066c 100644
--- a/tests/docker/dockerfiles/debian-tricore-cross.docker
+++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
@@ -19,6 +19,7 @@ RUN apt update && \
bison \
bzip2 \
ca-certificates \
+   flex \
ccache \
g++ \
gcc \
diff --git a/tests/docker/dockerfiles/debian10.docker 
b/tests/docker/dockerfiles/debian10.docker
index b414af1b9f..23285e7aa4 100644
--- a/tests/docker/dockerfiles/debian10.docker
+++ b/tests/docker/dockerfiles/debian10.docker
@@ -18,15 +18,18 @@ RUN apt update && \
 DEBIAN_FRONTEND=noninteractive eatmydata \
 apt install -y --no-install-recommends \
 bc \
+bison \
 build-essential \
 ca-certificates \
 ccache \
 clang \
 dbus \
+flex \
 gdb-multiarch \
 gettext \
 git \
 libffi-dev \
+libglib2.0-dev \
 libncurses5-dev \
 ninja-build \
 pkg-config \
diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker 
b/tests/docker/dockerfiles/fedora-i386-cross.docker
index 0a3ec346e6..7eec648d2d 100644
--- a/tests/docker/dockerfiles/fedora-i386-cross.docker
+++ b/tests/docker/dockerfiles/fedora-i386-cross.docker
@@ -1,9 +1,11 @@
 FROM registry.fedoraproject.org/fedora:34

 ENV PACKAGES \
+bison \
 bzip2 \
 ccache \
 diffutils \
+flex \
 findutils \
 gcc \
 git \
diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker 
b/tests/docker/dockerfiles/fedora-win32-cross.docker
index a06bd29e8e..aca37aabc4 100644
--- a/tests/docker/dockerfiles/fedora-win32-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win32-cross.docker
@@ -3,13 +3,16 @@ FROM registry.fedoraproject.org/fedora:35
 # Please keep this list sorted alphabetically
 ENV PACKAGES \
 bc \
+bison \
 bzip2 \
 ccache \
 diffutils \
 findutils \
+flex \
 gcc \
 gettext \
 git \
+glib2-devel \
 hostname \
 make \
 meson \
diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker 
b/tests/docker/dockerfiles/fedora-win64-cross.docker
index b71624330f..3642766479 100644
--- a/tests/docker/dockerfiles/fedora-win64-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win64-cross.docker
@@ -3,13 +3,16 @@ FROM registry.fedoraproject.org/fedora:35
 # Please keep this list sorted alphabetically
 ENV PACKAGES \
 bc \
+bison \
 bzip2 \
 ccache \
 diffutils \
 findutils \
+flex \
 gcc \
 gettext \
 git \
+glib2-devel \
 hostname \
 make \
 meson \
--
2.36.1



[PATCH v10 03/16] target/hexagon: make slot number an unsigned

2022-06-01 Thread Anton Johansson via
From: Paolo Montesel 

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

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index cd6af4bceb..df126de55b 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -30,7 +30,8 @@
 #include "gen_tcg.h"
 #include "gen_tcg_hvx.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_constant_tl(0);
 TCGv slot_mask = tcg_temp_new();
@@ -62,7 +63,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_constant_tl(0);
@@ -394,7 +396,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);
@@ -402,49 +404,49 @@ 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_constant_tl(src);
 gen_store1(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store2(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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_constant_tl(src);
 gen_store4(cpu_env, vaddr, tmp, ctx, slot);
 }
 
 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);
@@ -453,7 +455,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_constant_i64(src);
 gen_store8(cpu_env, vaddr, tmp, ctx, slot);
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index a78e84faa4..5ea2d54ebe 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_temp_new();
 TCGv tmp = tcg_temp_new();
-- 
2.36.1




[PATCH v10 16/16] target/hexagon: import additional tests

2022-06-01 Thread Anton Johansson via
From: Niccolò Izzo 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Niccolò Izzo 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 tests/tcg/hexagon/Makefile.target  | 28 -
 tests/tcg/hexagon/crt.S| 14 +++
 tests/tcg/hexagon/test_abs.S   | 17 
 tests/tcg/hexagon/test_bitcnt.S| 40 +++
 tests/tcg/hexagon/test_bitsplit.S  | 22 ++
 tests/tcg/hexagon/test_call.S  | 64 ++
 tests/tcg/hexagon/test_clobber.S   | 29 ++
 tests/tcg/hexagon/test_cmp.S   | 31 +++
 tests/tcg/hexagon/test_dotnew.S| 38 ++
 tests/tcg/hexagon/test_ext.S   | 13 ++
 tests/tcg/hexagon/test_fibonacci.S | 30 ++
 tests/tcg/hexagon/test_hl.S| 16 
 tests/tcg/hexagon/test_hwloops.S   | 19 +
 tests/tcg/hexagon/test_jmp.S   | 22 ++
 tests/tcg/hexagon/test_lsr.S   | 36 +
 tests/tcg/hexagon/test_mpyi.S  | 17 
 tests/tcg/hexagon/test_packet.S| 29 ++
 tests/tcg/hexagon/test_reorder.S   | 33 +++
 tests/tcg/hexagon/test_round.S | 29 ++
 tests/tcg/hexagon/test_vavgw.S | 31 +++
 tests/tcg/hexagon/test_vcmpb.S | 30 ++
 tests/tcg/hexagon/test_vcmpw.S | 30 ++
 tests/tcg/hexagon/test_vlsrw.S | 20 ++
 tests/tcg/hexagon/test_vmaxh.S | 35 
 tests/tcg/hexagon/test_vminh.S | 35 
 tests/tcg/hexagon/test_vpmpyh.S| 28 +
 tests/tcg/hexagon/test_vspliceb.S  | 31 +++
 27 files changed, 766 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_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_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_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 23b9870534..44ffa1337d 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
@@ -43,6 +43,32 @@ HEX_TESTS += atomics
 HEX_TESTS += fpstuff
 HEX_TESTS += overflow
 
+HEX_TESTS += test_abs
+HEX_TESTS += test_bitcnt
+HEX_TESTS += test_bitsplit
+HEX_TESTS += test_call
+HEX_TESTS += test_clobber
+HEX_TESTS += test_cmp
+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_packet
+HEX_TESTS += test_reorder
+HEX_TESTS += test_round
+HEX_TESTS += test_vavgw
+HEX_TESTS += test_vcmpb
+HEX_TESTS += test_vcmpw
+HEX_TESTS += test_vlsrw
+HEX_TESTS += test_vmaxh
+HEX_TESTS += test_vminh
+HEX_TESTS += test_vpmpyh
+HEX_TESTS += test_vspliceb
+
 TESTS += $(HEX_TESTS)
 
 # This test has to be compiled for the -mv67t target
diff --git a/tests/tcg/hexagon/crt.S b/tests/tcg/hexagon/crt.S
new file mode 100644
index 00..f9e6bc80f7
--- /dev/null
+++ b/tests/tcg/hexagon/crt.S
@@ -0,0 +1,14 @@
+#define SYS_exit_group 94
+
+.text
+.globl pass
+pass:
+r0 = #0
+r6 = #SYS_exit_group
+trap0(#1)
+
+.globl fail
+fail:
+r0 = #1
+r6 = #SYS_exit_group
+trap0(#1)
diff --git a/tests/tcg/hexagon/test_abs.S b/tests/tcg/hexagon/test_abs.S
new file mode 100644
index 00..d68aea6f64
--- /dev/null
+++ b/tests/tcg/hexagon/test_abs.S
@@ -0,0 +1,17 @@
+/* Purpose: test example, verify the soundness of the abs operation */
+
+.text
+.globl _start
+
+_start:
+{
+r1 = #-2
+r2 = #2
+}
+{
+  

[PATCH v10 13/16] target/hexagon: import lexer for idef-parser

2022-06-01 Thread Anton Johansson via
From: Paolo Montesel 

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Paolo Montesel 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 target/hexagon/idef-parser/idef-parser.h   | 253 +++
 target/hexagon/idef-parser/idef-parser.lex | 471 +
 target/hexagon/meson.build |   4 +
 3 files changed, 728 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..5c49d4da3e
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,253 @@
+/*
+ *  Copyright(c) 2019-2022 rev.ng Labs Srl. 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 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 } HexRegType;
+
+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   
*/
+HexRegType 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 {
+unsigned 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, used when type is VARIABLE   
*/
+uint64_t value; /**< Immediate value, used when type is VALUE 
*/
+uint64_t index; /**< Index, used when type is QEMU_TMP
*/
+};
+enum ImmUnionTag type;  /**< Type of the immediate
*/
+} HexImm;
+
+/**
+ * Semantic record of the PRED token, identifying a predicate
+ */
+typedef struct HexPred {
+char id;/**< Identifier of the predicate  
*/
+} HexPred;
+
+/**
+ * Semantic record of the SAT token, identifying the saturate operator
+ * Note: All saturates are assumed to implicitly set overflow.
+ */
+typedef struct HexSat {
+HexSignedness signedness;   /**< Signedness of the sat. op.   
*/
+} HexSat;
+
+/**
+ * Semantic record of the CAST token, identifying the cast operator
+ */
+typedef struct HexCast {
+unsigned bit_width; /**< Bit width of the cast operator   
*/
+HexSignedness signedness;   /**< Unsigned flag for the cast operator  
*/
+} HexCast;
+
+/**
+ * Semantic record of 

[PATCH v10 15/16] target/hexagon: call idef-parser functions

2022-06-01 Thread Anton Johansson 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. An option is also added to fully
disable the output of the idef-parser, which is useful for debugging
purposes.

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Anton Johansson 
Reviewed-by: Taylor Simpson 
---
 meson_options.txt   |  3 +
 target/hexagon/gen_helper_funcs.py  | 17 +-
 target/hexagon/gen_helper_protos.py | 17 +-
 target/hexagon/gen_tcg_funcs.py | 41 -
 target/hexagon/hex_common.py| 10 
 target/hexagon/meson.build  | 92 +++--
 6 files changed, 146 insertions(+), 34 deletions(-)

diff --git a/meson_options.txt b/meson_options.txt
index 2de94af037..fcc9027077 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -303,3 +303,6 @@ option('profiler', type: 'boolean', value: false,
description: 'profiler support')
 option('slirp_smbd', type : 'feature', value : 'auto',
description: 'use smbd (at path --smbd=*) in slirp networking')
+
+option('hexagon_idef_parser_enabled', type : 'boolean', value : true,
+   description: 'Whether idef-parser should be used to automatically 
generate TCG code for the Hexagon frontend')
diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index a446c45384..71d611283a 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -287,11 +287,24 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+is_idef_parser_enabled = len(sys.argv) > 6
+if is_idef_parser_enabled:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -308,6 +321,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 3b4e993fd1..74eff457a6 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -136,11 +136,24 @@ def main():
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.read_overrides_file(sys.argv[3])
 hex_common.read_overrides_file(sys.argv[4])
+## Whether or not idef-parser is enabled is
+## determined by the number of arguments to
+## this script:
+##
+##   5 args. -> not enabled,
+##   6 args. -> idef-parser enabled.
+##
+## The 6:th arg. then holds a list of the successfully
+## parsed instructions.
+is_idef_parser_enabled = len(sys.argv) > 6
+if is_idef_parser_enabled:
+hex_common.read_idef_parser_enabled_file(sys.argv[5])
 hex_common.calculate_attribs()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
-with open(sys.argv[5], 'w') as f:
+output_file = sys.argv[-1]
+with open(output_file, 'w') as f:
 for tag in hex_common.tags:
 ## Skip the priv instructions
 if ( "A_PRIV" in hex_common.attribdict[tag] ) :
@@ -158,6 +171,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 1fd9de95d5..4d12e192a7 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -610,7 +610,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, 

  1   2   3   4   5   >