From 84b3598bd0ea7a1e376c36b49b52db4740a3f9af Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 1 Sep 2006 21:44:18 +0000 Subject: [PATCH] Document multiclasses and defm's git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30030 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/TableGenFundamentals.html | 89 +++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index 7924bd9a2479..860f62093c34 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -30,6 +30,7 @@
  • Value definitions
  • 'let' expressions
  • Class template arguments
  • +
  • Multiclass definitions and instances
  • File scope entities
      @@ -102,6 +103,10 @@ definition, so the backend can find all definitions of a particular class, such as "Instruction".

      +

      TableGen multiclasses are groups of abstract records that are +instantiated all at once. Each instantiation can result in multiple TableGen +definitions.

      + @@ -463,16 +468,16 @@
       def bork {      // Value
      -  bit isMod = 1;
      -  bit isRef = 0;
      +  bit isMod = 1;
      +  bit isRef = 0;
       }
       def hork {      // Value
      -  bit isMod = 1;
      -  bit isRef = 1;
      +  bit isMod = 1;
      +  bit isRef = 1;
       }
       def zork {      // Value
      -  bit isMod = 0;
      -  bit isRef = 1;
      +  bit isMod = 0;
      +  bit isRef = 1;
       }
       
      @@ -483,6 +488,78 @@ + + + +
      + +

      +While classes with template arguments are a good way to factor commonality +between two instances of a definition, multiclasses allow a convenient notation +for defining multiple definitions at once (instances of implicitly constructed +classes). For example, consider an 3-address instruction set whose instructions +come in two forms: "reg = reg op reg" and "reg = reg op imm" (e.g. SPARC). In +this case, you'd like to specify in one place that this commonality exists, then +in a separate place indicate what all the ops are. +

      + +

      +Here is an example TableGen fragment that shows this idea: +

      + +
      +def ops;
      +def GPR;
      +def Imm;
      +class inst<int opc, string asmstr, dag operandlist>;
      +
      +multiclass ri_inst<int opc, string asmstr> {
      +  def _rr : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
      +                 (ops GPR:$dst, GPR:$src1, GPR:$src2)>;
      +  def _ri : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
      +                 (ops GPR:$dst, GPR:$src1, Imm:$src2)>;
      +}
      +
      +// Instantiations of the ri_inst multiclass.
      +defm ADD : ri_inst<0b111, "add">;
      +defm SUB : ri_inst<0b101, "sub">;
      +defm MUL : ri_inst<0b100, "mul">;
      +...
      +
      + +

      The name of the resuntant definitions has the multidef fragment names + appended to them, so this defines ADD_rr, ADD_ri, SUB_rr, etc. Using a + multiclass this way is exactly equivalent to instantiating the + classes multiple times yourself, e.g. by writing:

      + +
      +def ops;
      +def GPR;
      +def Imm;
      +class inst<int opc, string asmstr, dag operandlist>;
      +
      +class rrinst<int opc, string asmstr>
      +  : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
      +         (ops GPR:$dst, GPR:$src1, GPR:$src2)>;
      +
      +class riinst<int opc, string asmstr>
      +  : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
      +         (ops GPR:$dst, GPR:$src1, Imm:$src2)>;
      +
      +// Instantiations of the ri_inst multiclass.
      +def ADD_rr : rrinst<0b111, "add">;
      +def ADD_ri : riinst<0b111, "add">;
      +def SUB_rr : rrinst<0b101, "sub">;
      +def SUB_ri : riinst<0b101, "sub">;
      +def MUL_rr : rrinst<0b100, "mul">;
      +def MUL_ri : riinst<0b100, "mul">;
      +...
      +
      + +
      +