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