Merge tag 'qemu-macppc-20230206' of https://github.com/mcayland/qemu into staging
[qemu.git] / target / hexagon / README
blob6cb5affddb20f5b0481d557a5e1a006af5f27932
1 Hexagon is Qualcomm's very long instruction word (VLIW) digital signal
2 processor(DSP).  We also support Hexagon Vector eXtensions (HVX).  HVX
3 is a wide vector coprocessor designed for high performance computer vision,
4 image processing, machine learning, and other workloads.
6 The following versions of the Hexagon core are supported
7     Scalar core: v67
8     https://developer.qualcomm.com/downloads/qualcomm-hexagon-v67-programmer-s-reference-manual
9     HVX extension: v66
10     https://developer.qualcomm.com/downloads/qualcomm-hexagon-v66-hvx-programmer-s-reference-manual
12 We presented an overview of the project at the 2019 KVM Forum.
13     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
15 *** Tour of the code ***
17 The qemu-hexagon implementation is a combination of qemu and the Hexagon
18 architecture library (aka archlib).  The three primary directories with
19 Hexagon-specific code are
21     qemu/target/hexagon
22         This has all the instruction and packet semantics
23     qemu/target/hexagon/imported
24         These files are imported with very little modification from archlib
25         *.idef                  Instruction semantics definition
26         macros.def              Mapping of macros to instruction attributes
27         encode*.def             Encoding patterns for each instruction
28         iclass.def              Instruction class definitions used to determine
29                                 legal VLIW slots for each instruction
30     qemu/target/hexagon/idef-parser
31         Parser that, given the high-level definitions of an instruction,
32         produces a C function generating equivalent tiny code instructions.
33         See README.rst.
34     qemu/linux-user/hexagon
35         Helpers for loading the ELF file and making Linux system calls,
36         signals, etc
38 We start with scripts that generate a bunch of include files.  This
39 is a two step process.  The first step is to use the C preprocessor to expand
40 macros inside the architecture definition files.  This is done in
41 target/hexagon/gen_semantics.c.  This step produces
42     <BUILD_DIR>/target/hexagon/semantics_generated.pyinc.
43 That file is consumed by the following python scripts to produce the indicated
44 header files in <BUILD_DIR>/target/hexagon
45         gen_opcodes_def.py              -> opcodes_def_generated.h.inc
46         gen_op_regs.py                  -> op_regs_generated.h.inc
47         gen_printinsn.py                -> printinsn_generated.h.inc
48         gen_op_attribs.py               -> op_attribs_generated.h.inc
49         gen_helper_protos.py            -> helper_protos_generated.h.inc
50         gen_shortcode.py                -> shortcode_generated.h.inc
51         gen_tcg_funcs.py                -> tcg_funcs_generated.c.inc
52         gen_tcg_func_table.py           -> tcg_func_table_generated.c.inc
53         gen_helper_funcs.py             -> helper_funcs_generated.c.inc
54         gen_idef_parser_funcs.py        -> idef_parser_input.h
56 Qemu helper functions have 3 parts
57     DEF_HELPER declaration indicates the signature of the helper
58     gen_helper_<NAME> will generate a TCG call to the helper function
59     The helper implementation
61 Here's an example of the A2_add instruction.
62     Instruction tag        A2_add
63     Assembly syntax        "Rd32=add(Rs32,Rt32)"
64     Instruction semantics  "{ RdV=RsV+RtV;}"
66 By convention, the operands are identified by letter
67     RdV is the destination register
68     RsV, RtV are source registers
70 The generator uses the operand naming conventions (see large comment in
71 hex_common.py) to determine the signature of the helper function.  Here are the
72 results for A2_add
74 helper_protos_generated.h.inc
75     DEF_HELPER_3(A2_add, s32, env, s32, s32)
77 tcg_funcs_generated.c.inc
78     static void generate_A2_add(
79                     CPUHexagonState *env,
80                     DisasContext *ctx,
81                     Insn *insn,
82                     Packet *pkt)
83     {
84         TCGv RdV = tcg_temp_local_new();
85         const int RdN = insn->regno[0];
86         TCGv RsV = hex_gpr[insn->regno[1]];
87         TCGv RtV = hex_gpr[insn->regno[2]];
88         gen_helper_A2_add(RdV, cpu_env, RsV, RtV);
89         gen_log_reg_write(RdN, RdV);
90         ctx_log_reg_write(ctx, RdN);
91         tcg_temp_free(RdV);
92     }
94 helper_funcs_generated.c.inc
95     int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
96     {
97         uint32_t slot __attribute__((unused)) = 4;
98         int32_t RdV = 0;
99         { RdV=RsV+RtV;}
100         return RdV;
101     }
103 Note that generate_A2_add updates the disassembly context to be processed
104 when the packet commits (see "Packet Semantics" below).
106 The generator checks for fGEN_TCG_<tag> macro.  This allows us to generate
107 TCG code instead of a call to the helper.  If defined, the macro takes 1
108 argument.
109     C semantics (aka short code)
111 This allows the code generator to override the auto-generated code.  In some
112 cases this is necessary for correct execution.  We can also override for
113 faster emulation.  For example, calling a helper for add is more expensive
114 than generating a TCG add operation.
116 The gen_tcg.h file has any overrides. For example, we could write
117     #define fGEN_TCG_A2_add(GENHLPR, SHORTCODE) \
118         tcg_gen_add_tl(RdV, RsV, RtV)
120 The instruction semantics C code relies heavily on macros.  In cases where the
121 C semantics are specified only with macros, we can override the default with
122 the short semantics option and #define the macros to generate TCG code.  One
123 example is L2_loadw_locked:
124     Instruction tag        L2_loadw_locked
125     Assembly syntax        "Rd32=memw_locked(Rs32)"
126     Instruction semantics  "{ fEA_REG(RsV); fLOAD_LOCKED(1,4,u,EA,RdV) }"
128 In gen_tcg.h, we use the shortcode
129 #define fGEN_TCG_L2_loadw_locked(SHORTCODE) \
130     SHORTCODE
132 There are also cases where we brute force the TCG code generation.
133 Instructions with multiple definitions are examples.  These require special
134 handling because qemu helpers can only return a single value.
136 For HVX vectors, the generator behaves slightly differently.  The wide vectors
137 won't fit in a TCGv or TCGv_i64, so we pass TCGv_ptr variables to pass the
138 address to helper functions.  Here's an example for an HVX vector-add-word
139 istruction.
140     static void generate_V6_vaddw(
141                     CPUHexagonState *env,
142                     DisasContext *ctx,
143                     Insn *insn,
144                     Packet *pkt)
145     {
146         const int VdN = insn->regno[0];
147         const intptr_t VdV_off =
148             ctx_future_vreg_off(ctx, VdN, 1, true);
149         TCGv_ptr VdV = tcg_temp_local_new_ptr();
150         tcg_gen_addi_ptr(VdV, cpu_env, VdV_off);
151         const int VuN = insn->regno[1];
152         const intptr_t VuV_off =
153             vreg_src_off(ctx, VuN);
154         TCGv_ptr VuV = tcg_temp_local_new_ptr();
155         const int VvN = insn->regno[2];
156         const intptr_t VvV_off =
157             vreg_src_off(ctx, VvN);
158         TCGv_ptr VvV = tcg_temp_local_new_ptr();
159         tcg_gen_addi_ptr(VuV, cpu_env, VuV_off);
160         tcg_gen_addi_ptr(VvV, cpu_env, VvV_off);
161         TCGv slot = tcg_constant_tl(insn->slot);
162         gen_helper_V6_vaddw(cpu_env, VdV, VuV, VvV, slot);
163         tcg_temp_free(slot);
164         gen_log_vreg_write(ctx, VdV_off, VdN, EXT_DFL, insn->slot, false);
165         ctx_log_vreg_write(ctx, VdN, EXT_DFL, false);
166         tcg_temp_free_ptr(VdV);
167         tcg_temp_free_ptr(VuV);
168         tcg_temp_free_ptr(VvV);
169     }
171 Notice that we also generate a variable named <operand>_off for each operand of
172 the instruction.  This makes it easy to override the instruction semantics with
173 functions from tcg-op-gvec.h.  Here's the override for this instruction.
174     #define fGEN_TCG_V6_vaddw(SHORTCODE) \
175         tcg_gen_gvec_add(MO_32, VdV_off, VuV_off, VvV_off, \
176                          sizeof(MMVector), sizeof(MMVector))
178 Finally, we notice that the override doesn't use the TCGv_ptr variables, so
179 we don't generate them when an override is present.  Here is what we generate
180 when the override is present.
181     static void generate_V6_vaddw(
182                     CPUHexagonState *env,
183                     DisasContext *ctx,
184                     Insn *insn,
185                     Packet *pkt)
186     {
187         const int VdN = insn->regno[0];
188         const intptr_t VdV_off =
189             ctx_future_vreg_off(ctx, VdN, 1, true);
190         const int VuN = insn->regno[1];
191         const intptr_t VuV_off =
192             vreg_src_off(ctx, VuN);
193         const int VvN = insn->regno[2];
194         const intptr_t VvV_off =
195             vreg_src_off(ctx, VvN);
196         fGEN_TCG_V6_vaddw({ fHIDE(int i;) fVFOREACH(32, i) { VdV.w[i] = VuV.w[i] + VvV.w[i] ; } });
197         gen_log_vreg_write(ctx, VdV_off, VdN, EXT_DFL, insn->slot, false);
198         ctx_log_vreg_write(ctx, VdN, EXT_DFL, false);
199     }
201 In addition to instruction semantics, we use a generator to create the decode
202 tree.  This generation is also a two step process.  The first step is to run
203 target/hexagon/gen_dectree_import.c to produce
204     <BUILD_DIR>/target/hexagon/iset.py
205 This file is imported by target/hexagon/dectree.py to produce
206     <BUILD_DIR>/target/hexagon/dectree_generated.h.inc
208 *** Key Files ***
210 cpu.h
212 This file contains the definition of the CPUHexagonState struct.  It is the
213 runtime information for each thread and contains stuff like the GPR and
214 predicate registers.
216 macros.h
217 mmvec/macros.h
219 The Hexagon arch lib relies heavily on macros for the instruction semantics.
220 This is a great advantage for qemu because we can override them for different
221 purposes.  You will also notice there are sometimes two definitions of a macro.
222 The QEMU_GENERATE variable determines whether we want the macro to generate TCG
223 code.  If QEMU_GENERATE is not defined, we want the macro to generate vanilla
224 C code that will work in the helper implementation.
226 translate.c
228 The functions in this file generate TCG code for a translation block.  Some
229 important functions in this file are
231     gen_start_packet - initialize the data structures for packet semantics
232     gen_commit_packet - commit the register writes, stores, etc for a packet
233     decode_and_translate_packet - disassemble a packet and generate code
235 genptr.c
236 gen_tcg.h
238 These files create a function for each instruction.  It is mostly composed of
239 fGEN_TCG_<tag> definitions followed by including tcg_funcs_generated.c.inc.
241 op_helper.c
243 This file contains the implementations of all the helpers.  There are a few
244 general purpose helpers, but most of them are generated by including
245 helper_funcs_generated.c.inc.  There are also several helpers used for debugging.
248 *** Packet Semantics ***
250 VLIW packet semantics differ from serial semantics in that all input operands
251 are read, then the operations are performed, then all the results are written.
252 For exmaple, this packet performs a swap of registers r0 and r1
253     { r0 = r1; r1 = r0 }
254 Note that the result is different if the instructions are executed serially.
256 Packet semantics dictate that we defer any changes of state until the entire
257 packet is committed.  We record the results of each instruction in a side data
258 structure, and update the visible processor state when we commit the packet.
260 The data structures are divided between the runtime state and the translation
261 context.
263 During the TCG generation (see translate.[ch]), we use the DisasContext to
264 track what needs to be done during packet commit.  Here are the relevant
265 fields
267     reg_log            list of registers written
268     reg_log_idx        index into ctx_reg_log
269     pred_log           list of predicates written
270     pred_log_idx       index into ctx_pred_log
271     store_width        width of stores (indexed by slot)
273 During runtime, the following fields in CPUHexagonState (see cpu.h) are used
275     new_value             new value of a given register
276     reg_written           boolean indicating if register was written
277     new_pred_value        new value of a predicate register
278     pred_written          boolean indicating if predicate was written
279     mem_log_stores        record of the stores (indexed by slot)
281 For Hexagon Vector eXtensions (HVX), the following fields are used
282     VRegs                       Vector registers
283     future_VRegs                Registers to be stored during packet commit
284     tmp_VRegs                   Temporary registers *not* stored during commit
285     VRegs_updated               Mask of predicated vector writes
286     QRegs                       Q (vector predicate) registers
287     future_QRegs                Registers to be stored during packet commit
288     QRegs_updated               Mask of predicated vector writes
290 *** Debugging ***
292 You can turn on a lot of debugging by changing the HEX_DEBUG macro to 1 in
293 internal.h.  This will stream a lot of information as it generates TCG and
294 executes the code.
296 To track down nasty issues with Hexagon->TCG generation, we compare the
297 execution results with actual hardware running on a Hexagon Linux target.
298 Run qemu with the "-d cpu" option.  Then, we can diff the results and figure
299 out where qemu and hardware behave differently.
301 The stacks are located at different locations.  We handle this by changing
302 env->stack_adjust in translate.c.  First, set this to zero and run qemu.
303 Then, change env->stack_adjust to the difference between the two stack
304 locations.  Then rebuild qemu and run again. That will produce a very
305 clean diff.
307 Here are some handy places to set breakpoints
309     At the call to gen_start_packet for a given PC (note that the line number
310         might change in the future)
311         br translate.c:602 if ctx->base.pc_next == 0xdeadbeef
312     The helper function for each instruction is named helper_<TAG>, so here's
313         an example that will set a breakpoint at the start
314         br helper_A2_add
315     If you have the HEX_DEBUG macro set, the following will be useful
316         At the start of execution of a packet for a given PC
317             br helper_debug_start_packet if env->gpr[41] == 0xdeadbeef
318         At the end of execution of a packet for a given PC
319             br helper_debug_commit_end if env->this_PC == 0xdeadbeef