qemu/target/hexagon
Richard Henderson 873f9ca385 Accelerator patches
- Extract page-protection definitions to page-protection.h
 - Rework in accel/tcg in preparation of extracting TCG fields from CPUState
 - More uses of get_task_state() in user emulation
 - Xen refactors in preparation for adding multiple map caches (Juergen & Edgar)
 - MAINTAINERS updates (Aleksandar and Bin)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmY40CAACgkQ4+MsLN6t
 wN5drxAA1oIsuUzpAJmlMIxZwlzbICiuexgn/HH9DwWNlrarKo7V1l4YB8jd9WOg
 IKuj7c39kJKsDEB8BXApYwcly+l7DYdnAAI8Z7a+eN+ffKNl/0XBaLjsGf58RNwY
 fb39/cXWI9ZxKxsHMSyjpiu68gOGvZ5JJqa30Fr+eOGuug9Fn/fOe1zC6l/dMagy
 Dnym72stpD+hcsN5sVwohTBIk+7g9og1O/ctRx6Q3ZCOPz4p0+JNf8VUu43/reaR
 294yRK++JrSMhOVFRzP+FH1G25NxiOrVCFXZsUTYU+qPDtdiKtjH1keI/sk7rwZ7
 U573lesl7ewQFf1PvMdaVf0TrQyOe6kUGr9Mn2k8+KgjYRAjTAQk8V4Ric/+xXSU
 0rd7Cz7lyQ8jm0DoOElROv+lTDQs4dvm3BopF3Bojo4xHLHd3SFhROVPG4tvGQ3H
 72Q5UPR2Jr2QZKiImvPceUOg0z5XxoN6KRUkSEpMFOiTRkbwnrH59z/qPijUpe6v
 8l5IlI9GjwkL7pcRensp1VC6e9KC7F5Od1J/2RLDw3UQllMQXqVw2bxD3CEtDRJL
 QSZoS4d1jUCW4iAYdqh/8+2cOIPiCJ4ai5u7lSdjrIJkRErm32FV/pQLZauoHlT5
 eTPUgzDoRXVgI1X1slTpVXlEEvRNbhZqSkYLkXr80MLn5hTafo0=
 =3Qkg
 -----END PGP SIGNATURE-----

Merge tag 'accel-20240506' of https://github.com/philmd/qemu into staging

Accelerator patches

- Extract page-protection definitions to page-protection.h
- Rework in accel/tcg in preparation of extracting TCG fields from CPUState
- More uses of get_task_state() in user emulation
- Xen refactors in preparation for adding multiple map caches (Juergen & Edgar)
- MAINTAINERS updates (Aleksandar and Bin)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmY40CAACgkQ4+MsLN6t
# wN5drxAA1oIsuUzpAJmlMIxZwlzbICiuexgn/HH9DwWNlrarKo7V1l4YB8jd9WOg
# IKuj7c39kJKsDEB8BXApYwcly+l7DYdnAAI8Z7a+eN+ffKNl/0XBaLjsGf58RNwY
# fb39/cXWI9ZxKxsHMSyjpiu68gOGvZ5JJqa30Fr+eOGuug9Fn/fOe1zC6l/dMagy
# Dnym72stpD+hcsN5sVwohTBIk+7g9og1O/ctRx6Q3ZCOPz4p0+JNf8VUu43/reaR
# 294yRK++JrSMhOVFRzP+FH1G25NxiOrVCFXZsUTYU+qPDtdiKtjH1keI/sk7rwZ7
# U573lesl7ewQFf1PvMdaVf0TrQyOe6kUGr9Mn2k8+KgjYRAjTAQk8V4Ric/+xXSU
# 0rd7Cz7lyQ8jm0DoOElROv+lTDQs4dvm3BopF3Bojo4xHLHd3SFhROVPG4tvGQ3H
# 72Q5UPR2Jr2QZKiImvPceUOg0z5XxoN6KRUkSEpMFOiTRkbwnrH59z/qPijUpe6v
# 8l5IlI9GjwkL7pcRensp1VC6e9KC7F5Od1J/2RLDw3UQllMQXqVw2bxD3CEtDRJL
# QSZoS4d1jUCW4iAYdqh/8+2cOIPiCJ4ai5u7lSdjrIJkRErm32FV/pQLZauoHlT5
# eTPUgzDoRXVgI1X1slTpVXlEEvRNbhZqSkYLkXr80MLn5hTafo0=
# =3Qkg
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 06 May 2024 05:42:08 AM PDT
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]

* tag 'accel-20240506' of https://github.com/philmd/qemu: (28 commits)
  MAINTAINERS: Update my email address
  MAINTAINERS: Update Aleksandar Rikalo email
  system: Pass RAM MemoryRegion and is_write in xen_map_cache()
  xen: mapcache: Break out xen_map_cache_init_single()
  xen: mapcache: Break out xen_invalidate_map_cache_single()
  xen: mapcache: Refactor xen_invalidate_map_cache_entry_unlocked
  xen: mapcache: Refactor xen_replace_cache_entry_unlocked
  xen: mapcache: Break out xen_ram_addr_from_mapcache_single
  xen: mapcache: Refactor xen_remap_bucket for multi-instance
  xen: mapcache: Refactor xen_map_cache for multi-instance
  xen: mapcache: Refactor lock functions for multi-instance
  xen: let xen_ram_addr_from_mapcache() return -1 in case of not found entry
  system: let qemu_map_ram_ptr() use qemu_ram_ptr_length()
  user: Use get_task_state() helper
  user: Declare get_task_state() once in 'accel/tcg/vcpu-state.h'
  user: Forward declare TaskState type definition
  accel/tcg: Move @plugin_mem_cbs from CPUState to CPUNegativeOffsetState
  accel/tcg: Restrict cpu_plugin_mem_cbs_enabled() to TCG
  accel/tcg: Restrict qemu_plugin_vcpu_exit_hook() to TCG plugins
  accel/tcg: Update CPUNegativeOffsetState::can_do_io field documentation
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2024-05-06 10:19:10 -07:00
..
idef-parser hexagon: correct typos 2024-02-21 08:16:57 +03:00
imported target/hexagon: fix some occurrences of -Wshadow=local 2023-10-18 16:56:17 -07:00
mmvec Hexagon (target/hexagon) Remove uses of op_regs_generated.h.inc 2024-05-05 16:22:07 -07:00
arch.c Hexagon (target/hexagon) Short-circuit packet register writes 2023-05-18 12:40:52 -07:00
arch.h Hexagon (target/hexagon) CABAC decode bin 2021-05-01 16:06:11 -07:00
attribs_def.h.inc Hexagon (target/hexagon) Pass SP explicitly to helpers that need it 2024-05-05 16:22:07 -07:00
attribs.h Clean up decorations and whitespace around header guards 2022-05-11 16:50:32 +02:00
cpu_bits.h Hexagon (target/hexagon) change variables from int to bool when appropriate 2021-05-01 08:31:43 -07:00
cpu-param.h target/hexagon: Remove NB_MMU_MODES define 2023-03-13 06:44:37 -07:00
cpu-qom.h target: Move ArchCPUClass definition to 'cpu.h' 2023-11-07 13:08:48 +01:00
cpu.c accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
cpu.h include/exec: Implement cpu_mmu_index generically 2024-02-03 16:46:10 +10:00
decode.c Hexagon (target/hexagon) Remove uses of op_regs_generated.h.inc 2024-05-05 16:22:07 -07:00
decode.h Hexagon (target/hexagon) Use QEMU decodetree (32-bit instructions) 2024-01-21 22:02:33 -08:00
fma_emu.c hexagon: spelling fixes 2023-09-08 13:08:52 +03:00
fma_emu.h Hexagon (target/hexagon) properly handle denorm in arch_sf_recip_common 2022-03-12 09:14:22 -08:00
gdbstub.c target/hexagon: Prefer fast cpu_env() over slower CPU QOM cast macro 2024-03-12 11:46:17 +01:00
gen_analyze_funcs.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_decodetree.py Hexagon (target/hexagon) Use QEMU decodetree (16-bit instructions) 2024-01-21 22:02:40 -08:00
gen_dectree_import.c Hexagon (target/hexagon) Remove old dectree.py 2024-01-21 22:02:44 -08:00
gen_helper_funcs.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_helper_protos.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_idef_parser_funcs.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_op_attribs.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_opcodes_def.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_printinsn.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_semantics.c Hexagon HVX (target/hexagon) semantics generator 2021-11-03 16:01:29 -05:00
gen_tcg_func_table.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_tcg_funcs.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
gen_tcg_hvx.h tcg: Rename cpu_env to tcg_env 2023-10-03 08:01:02 -07:00
gen_tcg.h Hexagon (target/hexagon) Only pass env to generated helper when needed 2024-05-05 16:22:07 -07:00
gen_trans_funcs.py Hexagon (target/hexagon) Mark has_pred_dest in trans functions 2024-05-05 16:22:07 -07:00
genptr.c tcg: Rename cpu_env to tcg_env 2023-10-03 08:01:02 -07:00
genptr.h Hexagon (target/hexagon) Make special new_value for USR 2023-05-18 12:40:52 -07:00
helper.h Hexagon (target/hexagon) Move items to DisasContext 2023-05-18 12:40:52 -07:00
hex_arch_types.h target/hexagon: Clean up includes 2023-02-08 07:28:05 +01:00
hex_common.py Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
hex_regs.h target/hexagon: rename aliased register HEX_REG_P3_0 2023-01-05 09:19:02 -08:00
iclass.c Hexagon (iclass): update J4_hintjumpr slot constraints 2023-05-18 12:40:52 -07:00
iclass.h Hexagon (target/hexagon) instruction classes 2021-02-18 07:48:22 -08:00
insn.h Hexagon (target/hexagon) Mark has_pred_dest in trans functions 2024-05-05 16:22:07 -07:00
internal.h gdbstub: Change gdb_get_reg_cb and gdb_set_reg_cb 2024-02-28 09:09:49 +00:00
macros.h Hexagon (target/hexagon) Pass SP explicitly to helpers that need it 2024-05-05 16:22:07 -07:00
meson.build Hexagon (target/hexagon) Remove hex_common.read_attribs_file 2024-05-05 16:22:07 -07:00
op_helper.c target/hexagon: fix some occurrences of -Wshadow=local 2023-10-18 16:56:17 -07:00
op_helper.h target/hexagon: move GETPC() calls to top level helpers 2023-10-18 16:56:17 -07:00
opcodes.c Hexagon (target/hexagon) Remove gen_shortcode.py 2024-05-05 16:22:07 -07:00
opcodes.h Hexagon (target/hexagon) Remove uses of op_regs_generated.h.inc 2024-05-05 16:22:07 -07:00
printinsn.c Hexagon (target/hexagon) instruction printing 2021-02-18 07:48:22 -08:00
printinsn.h Hexagon (target/hexagon) instruction printing 2021-02-18 07:48:22 -08:00
README Hexagon (target/hexagon) Remove gen_shortcode.py 2024-05-05 16:22:07 -07:00
reg_fields_def.h.inc Hexagon (target/hexagon) register fields 2021-02-18 07:48:22 -08:00
reg_fields.c Hexagon (target/hexagon) cleanup reg_field_info definition 2021-05-01 08:31:43 -07:00
reg_fields.h Hexagon (target/hexagon) cleanup reg_field_info definition 2021-05-01 08:31:43 -07:00
translate.c Hexagon (target/hexagon) Enable more short-circuit packets (HVX) 2024-05-05 16:22:07 -07:00
translate.h Hexagon (target/hexagon) Enable more short-circuit packets (HVX) 2024-05-05 16:22:07 -07:00

Hexagon is Qualcomm's very long instruction word (VLIW) digital signal
processor(DSP).  We also support Hexagon Vector eXtensions (HVX).  HVX
is a wide vector coprocessor designed for high performance computer vision,
image processing, machine learning, and other workloads.

The following versions of the Hexagon core are supported
    Scalar core: v73
    https://developer.qualcomm.com/downloads/qualcomm-hexagon-v73-programmers-reference-manual-rev-aa
    HVX extension: v73
    https://developer.qualcomm.com/downloads/qualcomm-hexagon-v73-hvx-programmers-reference-manual-rev-aa

We presented an overview of the project at the 2019 KVM Forum.
    https://kvmforum2019.sched.com/event/Tmwc/qemu-hexagon-automatic-translation-of-the-isa-manual-pseudcode-to-tiny-code-instructions-of-a-vliw-architecture-niccolo-izzo-revng-taylor-simpson-qualcomm-innovation-center

*** Tour of the code ***

The qemu-hexagon implementation is a combination of qemu and the Hexagon
architecture library (aka archlib).  The three primary directories with
Hexagon-specific code are

    qemu/target/hexagon
        This has all the instruction and packet semantics
    qemu/target/hexagon/imported
        These files are imported with very little modification from archlib
        *.idef                  Instruction semantics definition
        macros.def              Mapping of macros to instruction attributes
        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

We start with scripts that generate a bunch of include files.  This
is a two step process.  The first step is to use the C preprocessor to expand
macros inside the architecture definition files.  This is done in
target/hexagon/gen_semantics.c.  This step produces
    <BUILD_DIR>/target/hexagon/semantics_generated.pyinc.
That file is consumed by the following python scripts to produce the indicated
header files in <BUILD_DIR>/target/hexagon
        gen_opcodes_def.py              -> opcodes_def_generated.h.inc
        gen_printinsn.py                -> printinsn_generated.h.inc
        gen_op_attribs.py               -> op_attribs_generated.h.inc
        gen_helper_protos.py            -> helper_protos_generated.h.inc
        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
        gen_analyze_funcs.py            -> analyze_funcs_generated.c.inc

Qemu helper functions have 3 parts
    DEF_HELPER declaration indicates the signature of the helper
    gen_helper_<NAME> will generate a TCG call to the helper function
    The helper implementation

Here's an example of the A2_add instruction.
    Instruction tag        A2_add
    Assembly syntax        "Rd32=add(Rs32,Rt32)"
    Instruction semantics  "{ RdV=RsV+RtV;}"

By convention, the operands are identified by letter
    RdV is the destination register
    RsV, RtV are source registers

The generator uses the operand naming conventions (see large comment in
hex_common.py) to determine the signature of the helper function.  Here are the
results for A2_add

helper_protos_generated.h.inc
    DEF_HELPER_3(A2_add, s32, env, s32, s32)

tcg_funcs_generated.c.inc
    static void generate_A2_add(
                    CPUHexagonState *env,
                    DisasContext *ctx,
                    Insn *insn,
                    Packet *pkt)
    {
        TCGv RdV = tcg_temp_new();
        const int RdN = insn->regno[0];
        TCGv RsV = hex_gpr[insn->regno[1]];
        TCGv RtV = hex_gpr[insn->regno[2]];
        gen_helper_A2_add(RdV, tcg_env, RsV, RtV);
        gen_log_reg_write(ctx, RdN, RdV);
    }

helper_funcs_generated.c.inc
    int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
    {
        uint32_t slot __attribute__((unused)) = 4;
        int32_t RdV = 0;
        { RdV=RsV+RtV;}
        return RdV;
    }

Note that generate_A2_add updates the disassembly context to be processed
when the packet commits (see "Packet Semantics" below).

The generator checks for fGEN_TCG_<tag> macro.  This allows us to generate
TCG code instead of a call to the helper.  If defined, the macro takes 1
argument.
    C semantics (aka short code)

This allows the code generator to override the auto-generated code.  In some
cases this is necessary for correct execution.  We can also override for
faster emulation.  For example, calling a helper for add is more expensive
than generating a TCG add operation.

The gen_tcg.h file has any overrides. For example, we could write
    #define fGEN_TCG_A2_add(GENHLPR, SHORTCODE) \
        tcg_gen_add_tl(RdV, RsV, RtV)

The instruction semantics C code relies heavily on macros.  In cases where the
C semantics are specified only with macros, we can override the default with
the short semantics option and #define the macros to generate TCG code.  One
example is L2_loadw_locked:
    Instruction tag        L2_loadw_locked
    Assembly syntax        "Rd32=memw_locked(Rs32)"
    Instruction semantics  "{ fEA_REG(RsV); fLOAD_LOCKED(1,4,u,EA,RdV) }"

In gen_tcg.h, we use the shortcode
#define fGEN_TCG_L2_loadw_locked(SHORTCODE) \
    SHORTCODE

There are also cases where we brute force the TCG code generation.
Instructions with multiple definitions are examples.  These require special
handling because qemu helpers can only return a single value.

For HVX vectors, the generator behaves slightly differently.  The wide vectors
won't fit in a TCGv or TCGv_i64, so we pass TCGv_ptr variables to pass the
address to helper functions.  Here's an example for an HVX vector-add-word
istruction.
    static void generate_V6_vaddw(DisasContext *ctx)
    {
        Insn *insn __attribute__((unused)) = ctx->insn;
        const int VdN = insn->regno[0];
        const intptr_t VdV_off =
            ctx_future_vreg_off(ctx, VdN, 1, true);
        TCGv_ptr VdV = tcg_temp_new_ptr();
        tcg_gen_addi_ptr(VdV, tcg_env, VdV_off);
        const int VuN = insn->regno[1];
        const intptr_t VuV_off =
            vreg_src_off(ctx, VuN);
        TCGv_ptr VuV = tcg_temp_new_ptr();
        const int VvN = insn->regno[2];
        const intptr_t VvV_off =
            vreg_src_off(ctx, VvN);
        TCGv_ptr VvV = tcg_temp_new_ptr();
        tcg_gen_addi_ptr(VuV, tcg_env, VuV_off);
        tcg_gen_addi_ptr(VvV, tcg_env, VvV_off);
        gen_helper_V6_vaddw(tcg_env, VdV, VuV, VvV);
    }

Notice that we also generate a variable named <operand>_off for each operand of
the instruction.  This makes it easy to override the instruction semantics with
functions from tcg-op-gvec.h.  Here's the override for this instruction.
    #define fGEN_TCG_V6_vaddw(SHORTCODE) \
        tcg_gen_gvec_add(MO_32, VdV_off, VuV_off, VvV_off, \
                         sizeof(MMVector), sizeof(MMVector))

Finally, we notice that the override doesn't use the TCGv_ptr variables, so
we don't generate them when an override is present.  Here is what we generate
when the override is present.
    static void generate_V6_vaddw(DisasContext *ctx)
    {
        Insn *insn __attribute__((unused)) = ctx->insn;
        const int VdN = insn->regno[0];
        const intptr_t VdV_off =
            ctx_future_vreg_off(ctx, VdN, 1, true);
        const int VuN = insn->regno[1];
        const intptr_t VuV_off =
            vreg_src_off(ctx, VuN);
        const int VvN = insn->regno[2];
        const intptr_t VvV_off =
            vreg_src_off(ctx, VvN);
        fGEN_TCG_V6_vaddw({ fHIDE(int i;) fVFOREACH(32, i) { VdV.w[i] = VuV.w[i] + VvV.w[i] ; } });
    }

We also generate an analyze_<tag> function for each instruction.  Currently,
these functions record the reads and writes to registers by calling ctx_log_*.
During gen_start_packet, we invoke the analyze_<tag> function for each instruction in
the packet, and we mark the implicit writes.  The analysis determines if the packet
semantics can be short-circuited.  If not, we initialize the result register for each
of the predicated assignments.

In addition to instruction semantics, we use a generator to create the decode
tree.  This generation is a four step process.
Step 1 is to run target/hexagon/gen_dectree_import.c to produce
    <BUILD_DIR>/target/hexagon/iset.py
Step 2 is to import iset.py into target/hexagon/gen_decodetree.py to produce
    <BUILD_DIR>/target/hexagon/normal_decode_generated
    <BUILD_DIR>/target/hexagon/hvx_decode_generated
    <BUILD_DIR>/target/hexagon/subinsn_*_decode_generated
Step 3 is to process the above files with QEMU's decodetree.py to produce
    <BUILD_DIR>/target/hexagon/decode_*_generated.c.inc
Step 4 is to import iset.py into target/hexagon/gen_trans_funcs.py to produce
    <BUILD_DIR>/target/hexagon/decodetree_trans_funcs_generated.c.inc

*** Key Files ***

cpu.h

This file contains the definition of the CPUHexagonState struct.  It is the
runtime information for each thread and contains stuff like the GPR and
predicate registers.

macros.h
mmvec/macros.h

The Hexagon arch lib relies heavily on macros for the instruction semantics.
This is a great advantage for qemu because we can override them for different
purposes.  You will also notice there are sometimes two definitions of a macro.
The QEMU_GENERATE variable determines whether we want the macro to generate TCG
code.  If QEMU_GENERATE is not defined, we want the macro to generate vanilla
C code that will work in the helper implementation.

translate.c

The functions in this file generate TCG code for a translation block.  Some
important functions in this file are

    gen_start_packet - initialize the data structures for packet semantics
    gen_commit_packet - commit the register writes, stores, etc for a packet
    decode_and_translate_packet - disassemble a packet and generate code

genptr.c
gen_tcg.h

These files create a function for each instruction.  It is mostly composed of
fGEN_TCG_<tag> definitions followed by including tcg_funcs_generated.c.inc.

op_helper.c

This file contains the implementations of all the helpers.  There are a few
general purpose helpers, but most of them are generated by including
helper_funcs_generated.c.inc.  There are also several helpers used for debugging.


*** Packet Semantics ***

VLIW packet semantics differ from serial semantics in that all input operands
are read, then the operations are performed, then all the results are written.
For example, this packet performs a swap of registers r0 and r1
    { r0 = r1; r1 = r0 }
Note that the result is different if the instructions are executed serially.

Packet semantics dictate that we defer any changes of state until the entire
packet is committed.  We record the results of each instruction in a side data
structure, and update the visible processor state when we commit the packet.

The data structures are divided between the runtime state and the translation
context.

During the TCG generation (see translate.[ch]), we use the DisasContext to
track what needs to be done during packet commit.  Here are the relevant
fields

    reg_log            list of registers written
    reg_log_idx        index into ctx_reg_log
    pred_log           list of predicates written
    pred_log_idx       index into ctx_pred_log
    store_width        width of stores (indexed by slot)

During runtime, the following fields in CPUHexagonState (see cpu.h) are used

    new_value             new value of a given register
    reg_written           boolean indicating if register was written
    new_pred_value        new value of a predicate register
    pred_written          boolean indicating if predicate was written
    mem_log_stores        record of the stores (indexed by slot)

For Hexagon Vector eXtensions (HVX), the following fields are used
    VRegs                       Vector registers
    future_VRegs                Registers to be stored during packet commit
    tmp_VRegs                   Temporary registers *not* stored during commit
    QRegs                       Q (vector predicate) registers
    future_QRegs                Registers to be stored during packet commit

*** Debugging ***

You can turn on a lot of debugging by changing the HEX_DEBUG macro to 1 in
internal.h.  This will stream a lot of information as it generates TCG and
executes the code.

To track down nasty issues with Hexagon->TCG generation, we compare the
execution results with actual hardware running on a Hexagon Linux target.
Run qemu with the "-d cpu" option.  Then, we can diff the results and figure
out where qemu and hardware behave differently.

The stacks are located at different locations.  We handle this by changing
env->stack_adjust in translate.c.  First, set this to zero and run qemu.
Then, change env->stack_adjust to the difference between the two stack
locations.  Then rebuild qemu and run again. That will produce a very
clean diff.

Here are some handy places to set breakpoints

    At the call to gen_start_packet for a given PC (note that the line number
        might change in the future)
        br translate.c:602 if ctx->base.pc_next == 0xdeadbeef
    The helper function for each instruction is named helper_<TAG>, so here's
        an example that will set a breakpoint at the start
        br helper_A2_add
    If you have the HEX_DEBUG macro set, the following will be useful
        At the start of execution of a packet for a given PC
            br helper_debug_start_packet if env->gpr[41] == 0xdeadbeef
        At the end of execution of a packet for a given PC
            br helper_debug_commit_end if this_PC == 0xdeadbeef