Merge tag 'pull-loongarch-20241016' of https://gitlab.com/gaosong/qemu into staging
[qemu/armbru.git] / target / hexagon / README
blob7ffd517d70607424b398b60f591ee0ed17c7bf4f
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: v73
8     https://developer.qualcomm.com/downloads/qualcomm-hexagon-v73-programmers-reference-manual-rev-aa
9     HVX extension: v73
10     https://developer.qualcomm.com/downloads/qualcomm-hexagon-v73-hvx-programmers-reference-manual-rev-aa
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_printinsn.py                -> printinsn_generated.h.inc
47         gen_op_attribs.py               -> op_attribs_generated.h.inc
48         gen_helper_protos.py            -> helper_protos_generated.h.inc
49         gen_tcg_funcs.py                -> tcg_funcs_generated.c.inc
50         gen_tcg_func_table.py           -> tcg_func_table_generated.c.inc
51         gen_helper_funcs.py             -> helper_funcs_generated.c.inc
52         gen_idef_parser_funcs.py        -> idef_parser_input.h
53         gen_analyze_funcs.py            -> analyze_funcs_generated.c.inc
55 Qemu helper functions have 3 parts
56     DEF_HELPER declaration indicates the signature of the helper
57     gen_helper_<NAME> will generate a TCG call to the helper function
58     The helper implementation
60 Here's an example of the A2_add instruction.
61     Instruction tag        A2_add
62     Assembly syntax        "Rd32=add(Rs32,Rt32)"
63     Instruction semantics  "{ RdV=RsV+RtV;}"
65 By convention, the operands are identified by letter
66     RdV is the destination register
67     RsV, RtV are source registers
69 The generator uses the operand naming conventions (see large comment in
70 hex_common.py) to determine the signature of the helper function.  Here are the
71 results for A2_add
73 helper_protos_generated.h.inc
74     DEF_HELPER_3(A2_add, s32, env, s32, s32)
76 tcg_funcs_generated.c.inc
77     static void generate_A2_add(
78                     CPUHexagonState *env,
79                     DisasContext *ctx,
80                     Insn *insn,
81                     Packet *pkt)
82     {
83         TCGv RdV = tcg_temp_new();
84         const int RdN = insn->regno[0];
85         TCGv RsV = hex_gpr[insn->regno[1]];
86         TCGv RtV = hex_gpr[insn->regno[2]];
87         gen_helper_A2_add(RdV, tcg_env, RsV, RtV);
88         gen_log_reg_write(ctx, RdN, RdV);
89     }
91 helper_funcs_generated.c.inc
92     int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
93     {
94         uint32_t slot __attribute__((unused)) = 4;
95         int32_t RdV = 0;
96         { RdV=RsV+RtV;}
97         return RdV;
98     }
100 Note that generate_A2_add updates the disassembly context to be processed
101 when the packet commits (see "Packet Semantics" below).
103 The generator checks for fGEN_TCG_<tag> macro.  This allows us to generate
104 TCG code instead of a call to the helper.  If defined, the macro takes 1
105 argument.
106     C semantics (aka short code)
108 This allows the code generator to override the auto-generated code.  In some
109 cases this is necessary for correct execution.  We can also override for
110 faster emulation.  For example, calling a helper for add is more expensive
111 than generating a TCG add operation.
113 The gen_tcg.h file has any overrides. For example, we could write
114     #define fGEN_TCG_A2_add(GENHLPR, SHORTCODE) \
115         tcg_gen_add_tl(RdV, RsV, RtV)
117 The instruction semantics C code relies heavily on macros.  In cases where the
118 C semantics are specified only with macros, we can override the default with
119 the short semantics option and #define the macros to generate TCG code.  One
120 example is L2_loadw_locked:
121     Instruction tag        L2_loadw_locked
122     Assembly syntax        "Rd32=memw_locked(Rs32)"
123     Instruction semantics  "{ fEA_REG(RsV); fLOAD_LOCKED(1,4,u,EA,RdV) }"
125 In gen_tcg.h, we use the shortcode
126 #define fGEN_TCG_L2_loadw_locked(SHORTCODE) \
127     SHORTCODE
129 There are also cases where we brute force the TCG code generation.
130 Instructions with multiple definitions are examples.  These require special
131 handling because qemu helpers can only return a single value.
133 For HVX vectors, the generator behaves slightly differently.  The wide vectors
134 won't fit in a TCGv or TCGv_i64, so we pass TCGv_ptr variables to pass the
135 address to helper functions.  Here's an example for an HVX vector-add-word
136 istruction.
137     static void generate_V6_vaddw(DisasContext *ctx)
138     {
139         Insn *insn __attribute__((unused)) = ctx->insn;
140         const int VdN = insn->regno[0];
141         const intptr_t VdV_off =
142             ctx_future_vreg_off(ctx, VdN, 1, true);
143         TCGv_ptr VdV = tcg_temp_new_ptr();
144         tcg_gen_addi_ptr(VdV, tcg_env, VdV_off);
145         const int VuN = insn->regno[1];
146         const intptr_t VuV_off =
147             vreg_src_off(ctx, VuN);
148         TCGv_ptr VuV = tcg_temp_new_ptr();
149         const int VvN = insn->regno[2];
150         const intptr_t VvV_off =
151             vreg_src_off(ctx, VvN);
152         TCGv_ptr VvV = tcg_temp_new_ptr();
153         tcg_gen_addi_ptr(VuV, tcg_env, VuV_off);
154         tcg_gen_addi_ptr(VvV, tcg_env, VvV_off);
155         gen_helper_V6_vaddw(tcg_env, VdV, VuV, VvV);
156     }
158 Notice that we also generate a variable named <operand>_off for each operand of
159 the instruction.  This makes it easy to override the instruction semantics with
160 functions from tcg-op-gvec.h.  Here's the override for this instruction.
161     #define fGEN_TCG_V6_vaddw(SHORTCODE) \
162         tcg_gen_gvec_add(MO_32, VdV_off, VuV_off, VvV_off, \
163                          sizeof(MMVector), sizeof(MMVector))
165 Finally, we notice that the override doesn't use the TCGv_ptr variables, so
166 we don't generate them when an override is present.  Here is what we generate
167 when the override is present.
168     static void generate_V6_vaddw(DisasContext *ctx)
169     {
170         Insn *insn __attribute__((unused)) = ctx->insn;
171         const int VdN = insn->regno[0];
172         const intptr_t VdV_off =
173             ctx_future_vreg_off(ctx, VdN, 1, true);
174         const int VuN = insn->regno[1];
175         const intptr_t VuV_off =
176             vreg_src_off(ctx, VuN);
177         const int VvN = insn->regno[2];
178         const intptr_t VvV_off =
179             vreg_src_off(ctx, VvN);
180         fGEN_TCG_V6_vaddw({ fHIDE(int i;) fVFOREACH(32, i) { VdV.w[i] = VuV.w[i] + VvV.w[i] ; } });
181     }
183 We also generate an analyze_<tag> function for each instruction.  Currently,
184 these functions record the reads and writes to registers by calling ctx_log_*.
185 During gen_start_packet, we invoke the analyze_<tag> function for each instruction in
186 the packet, and we mark the implicit writes.  The analysis determines if the packet
187 semantics can be short-circuited.  If not, we initialize the result register for each
188 of the predicated assignments.
190 In addition to instruction semantics, we use a generator to create the decode
191 tree.  This generation is a four step process.
192 Step 1 is to run target/hexagon/gen_dectree_import.c to produce
193     <BUILD_DIR>/target/hexagon/iset.py
194 Step 2 is to import iset.py into target/hexagon/gen_decodetree.py to produce
195     <BUILD_DIR>/target/hexagon/normal_decode_generated
196     <BUILD_DIR>/target/hexagon/hvx_decode_generated
197     <BUILD_DIR>/target/hexagon/subinsn_*_decode_generated
198 Step 3 is to process the above files with QEMU's decodetree.py to produce
199     <BUILD_DIR>/target/hexagon/decode_*_generated.c.inc
200 Step 4 is to import iset.py into target/hexagon/gen_trans_funcs.py to produce
201     <BUILD_DIR>/target/hexagon/decodetree_trans_funcs_generated.c.inc
203 *** Key Files ***
205 cpu.h
207 This file contains the definition of the CPUHexagonState struct.  It is the
208 runtime information for each thread and contains stuff like the GPR and
209 predicate registers.
211 macros.h
212 mmvec/macros.h
214 The Hexagon arch lib relies heavily on macros for the instruction semantics.
215 This is a great advantage for qemu because we can override them for different
216 purposes.  You will also notice there are sometimes two definitions of a macro.
217 The QEMU_GENERATE variable determines whether we want the macro to generate TCG
218 code.  If QEMU_GENERATE is not defined, we want the macro to generate vanilla
219 C code that will work in the helper implementation.
221 translate.c
223 The functions in this file generate TCG code for a translation block.  Some
224 important functions in this file are
226     gen_start_packet - initialize the data structures for packet semantics
227     gen_commit_packet - commit the register writes, stores, etc for a packet
228     decode_and_translate_packet - disassemble a packet and generate code
230 genptr.c
231 gen_tcg.h
233 These files create a function for each instruction.  It is mostly composed of
234 fGEN_TCG_<tag> definitions followed by including tcg_funcs_generated.c.inc.
236 op_helper.c
238 This file contains the implementations of all the helpers.  There are a few
239 general purpose helpers, but most of them are generated by including
240 helper_funcs_generated.c.inc.  There are also several helpers used for debugging.
243 *** Packet Semantics ***
245 VLIW packet semantics differ from serial semantics in that all input operands
246 are read, then the operations are performed, then all the results are written.
247 For example, this packet performs a swap of registers r0 and r1
248     { r0 = r1; r1 = r0 }
249 Note that the result is different if the instructions are executed serially.
251 Packet semantics dictate that we defer any changes of state until the entire
252 packet is committed.  We record the results of each instruction in a side data
253 structure, and update the visible processor state when we commit the packet.
255 The data structures are divided between the runtime state and the translation
256 context.
258 During the TCG generation (see translate.[ch]), we use the DisasContext to
259 track what needs to be done during packet commit.  Here are the relevant
260 fields
262     reg_log            list of registers written
263     reg_log_idx        index into ctx_reg_log
264     pred_log           list of predicates written
265     pred_log_idx       index into ctx_pred_log
266     store_width        width of stores (indexed by slot)
268 During runtime, the following fields in CPUHexagonState (see cpu.h) are used
270     new_value             new value of a given register
271     reg_written           boolean indicating if register was written
272     new_pred_value        new value of a predicate register
273     pred_written          boolean indicating if predicate was written
274     mem_log_stores        record of the stores (indexed by slot)
276 For Hexagon Vector eXtensions (HVX), the following fields are used
277     VRegs                       Vector registers
278     future_VRegs                Registers to be stored during packet commit
279     tmp_VRegs                   Temporary registers *not* stored during commit
280     QRegs                       Q (vector predicate) registers
281     future_QRegs                Registers to be stored during packet commit
283 *** Debugging ***
285 You can turn on a lot of debugging by changing the HEX_DEBUG macro to 1 in
286 internal.h.  This will stream a lot of information as it generates TCG and
287 executes the code.
289 To track down nasty issues with Hexagon->TCG generation, we compare the
290 execution results with actual hardware running on a Hexagon Linux target.
291 Run qemu with the "-d cpu" option.  Then, we can diff the results and figure
292 out where qemu and hardware behave differently.
294 The stacks are located at different locations.  We handle this by changing
295 env->stack_adjust in translate.c.  First, set this to zero and run qemu.
296 Then, change env->stack_adjust to the difference between the two stack
297 locations.  Then rebuild qemu and run again. That will produce a very
298 clean diff.
300 Here are some handy places to set breakpoints
302     At the call to gen_start_packet for a given PC (note that the line number
303         might change in the future)
304         br translate.c:602 if ctx->base.pc_next == 0xdeadbeef
305     The helper function for each instruction is named helper_<TAG>, so here's
306         an example that will set a breakpoint at the start
307         br helper_A2_add
308     If you have the HEX_DEBUG macro set, the following will be useful
309         At the start of execution of a packet for a given PC
310             br helper_debug_start_packet if env->gpr[41] == 0xdeadbeef
311         At the end of execution of a packet for a given PC
312             br helper_debug_commit_end if this_PC == 0xdeadbeef