X86DisassemblerTables.h revision 221345
149884Ssheldonh//===- X86DisassemblerTables.h - Disassembler tables ------------*- C++ -*-===//
249884Ssheldonh//
349884Ssheldonh//                     The LLVM Compiler Infrastructure
449884Ssheldonh//
549884Ssheldonh// This file is distributed under the University of Illinois Open Source
649884Ssheldonh// License. See LICENSE.TXT for details.
749884Ssheldonh//
849884Ssheldonh//===----------------------------------------------------------------------===//
91556Srgrimes//
1049884Ssheldonh// This file is part of the X86 Disassembler Emitter.
111556Srgrimes// It contains the interface of the disassembler tables.
121556Srgrimes// Documentation for the disassembler emitter in general can be found in
131556Srgrimes//  X86DisasemblerEmitter.h.
1436152Scharnier//
1550471Speter//===----------------------------------------------------------------------===//
161556Srgrimes
171556Srgrimes#ifndef X86DISASSEMBLERTABLES_H
1849884Ssheldonh#define X86DISASSEMBLERTABLES_H
191556Srgrimes
201556Srgrimes#include "X86DisassemblerShared.h"
211556Srgrimes#include "X86ModRMFilters.h"
221556Srgrimes
231556Srgrimes#include "llvm/Support/raw_ostream.h"
2476883Skris
251556Srgrimes#include <vector>
261556Srgrimes
271556Srgrimesnamespace llvm {
281556Srgrimes
291556Srgrimesnamespace X86Disassembler {
3049884Ssheldonh
3149884Ssheldonh/// DisassemblerTables - Encapsulates all the decode tables being generated by
3249884Ssheldonh///   the table emitter.  Contains functions to populate the tables as well as
3349884Ssheldonh///   to emit them as hierarchical C structures suitable for consumption by the
3449884Ssheldonh///   runtime.
3549884Ssheldonhclass DisassemblerTables {
3649884Ssheldonhprivate:
3749884Ssheldonh  /// The decoder tables.  There is one for each opcode type:
3849884Ssheldonh  /// [0] one-byte opcodes
3949884Ssheldonh  /// [1] two-byte opcodes of the form 0f __
4049884Ssheldonh  /// [2] three-byte opcodes of the form 0f 38 __
411556Srgrimes  /// [3] three-byte opcodes of the form 0f 3a __
4249884Ssheldonh  /// [4] three-byte opcodes of the form 0f a6 __
4349884Ssheldonh  /// [5] three-byte opcodes of the form 0f a7 __
4449884Ssheldonh  ContextDecision* Tables[6];
4549884Ssheldonh
461556Srgrimes  /// The instruction information table
4749884Ssheldonh  std::vector<InstructionSpecifier> InstructionSpecifiers;
4849884Ssheldonh
4949884Ssheldonh  /// True if there are primary decode conflicts in the instruction set
5049884Ssheldonh  bool HasConflicts;
5149884Ssheldonh
5249884Ssheldonh  /// emitOneID - Emits a table entry for a single instruction entry, at the
5349884Ssheldonh  ///   innermost level of the structure hierarchy.  The entry is printed out
5449884Ssheldonh  ///   in the format "nnnn, /* MNEMONIC */" where nnnn is the ID in decimal,
5549884Ssheldonh  ///   the comma is printed if addComma is true, and the menonic is the name
5649884Ssheldonh  ///   of the instruction as listed in the LLVM tables.
5749884Ssheldonh  ///
5849884Ssheldonh  /// @param o        - The output stream to print the entry on.
5949884Ssheldonh  /// @param i        - The indentation level for o.
6049884Ssheldonh  /// @param id       - The unique ID of the instruction to print.
6149884Ssheldonh  /// @param addComma - Whether or not to print a comma after the ID.  True if
6249884Ssheldonh  ///                    additional items will follow.
6349884Ssheldonh  void emitOneID(raw_ostream &o,
6449884Ssheldonh                 uint32_t &i,
6549884Ssheldonh                 InstrUID id,
6649884Ssheldonh                 bool addComma) const;
6749884Ssheldonh
6849884Ssheldonh  /// emitModRMDecision - Emits a table of entries corresponding to a single
6949884Ssheldonh  ///   ModR/M decision.  Compacts the ModR/M decision if possible.  ModR/M
7049884Ssheldonh  ///   decisions are printed as:
7149884Ssheldonh  ///
7249884Ssheldonh  ///   { /* struct ModRMDecision */
7349884Ssheldonh  ///     TYPE,
7449884Ssheldonh  ///     modRMTablennnn
7549884Ssheldonh  ///   }
7649884Ssheldonh  ///
7749884Ssheldonh  ///   where nnnn is a unique ID for the corresponding table of IDs.
7849884Ssheldonh  ///   TYPE indicates whether the table has one entry that is the same
7949884Ssheldonh  ///   regardless of ModR/M byte, two entries - one for bytes 0x00-0xbf and one
8049884Ssheldonh  ///   for bytes 0xc0-0xff -, or 256 entries, one for each possible byte.
8149884Ssheldonh  ///   nnnn is the number of a table for looking up these values.  The tables
8249884Ssheldonh  ///   are written separately so that tables consisting entirely of zeros will
8349884Ssheldonh  ///   not be duplicated.  (These all have the name modRMEmptyTable.)  A table
8449884Ssheldonh  ///   is printed as:
8549884Ssheldonh  ///
8649884Ssheldonh  ///   InstrUID modRMTablennnn[k] = {
8749884Ssheldonh  ///     nnnn, /* MNEMONIC */
881556Srgrimes  ///     ...
891556Srgrimes  ///     nnnn /* MNEMONIC */
9049884Ssheldonh  ///   };
9149884Ssheldonh  ///
9249884Ssheldonh  /// @param o1       - The output stream to print the ID table to.
9349884Ssheldonh  /// @param o2       - The output stream to print the decision structure to.
9449884Ssheldonh  /// @param i1       - The indentation level to use with stream o1.
9549884Ssheldonh  /// @param i2       - The indentation level to use with stream o2.
961556Srgrimes  /// @param decision - The ModR/M decision to emit.  This decision has 256
971556Srgrimes  ///                   entries - emitModRMDecision decides how to compact it.
9849884Ssheldonh  void emitModRMDecision(raw_ostream &o1,
9949884Ssheldonh                         raw_ostream &o2,
10049884Ssheldonh                         uint32_t &i1,
10149884Ssheldonh                         uint32_t &i2,
10249884Ssheldonh                         ModRMDecision &decision) const;
10349884Ssheldonh
10449884Ssheldonh  /// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M
10549884Ssheldonh  ///   decisions.  An OpcodeDecision is printed as:
10649884Ssheldonh  ///
10749884Ssheldonh  ///   { /* struct OpcodeDecision */
10849884Ssheldonh  ///     /* 0x00 */
10949884Ssheldonh  ///     { /* struct ModRMDecision */
11049884Ssheldonh  ///       ...
11149884Ssheldonh  ///     }
11249884Ssheldonh  ///     ...
11349884Ssheldonh  ///   }
11449884Ssheldonh  ///
11549884Ssheldonh  ///   where the ModRMDecision structure is printed as described in the
11649884Ssheldonh  ///   documentation for emitModRMDecision().  emitOpcodeDecision() passes on a
11749884Ssheldonh  ///   stream and indent level for the UID tables generated by
11849884Ssheldonh  ///   emitModRMDecision(), but does not use them itself.
11949884Ssheldonh  ///
12049884Ssheldonh  /// @param o1       - The output stream to print the ID tables generated by
12149884Ssheldonh  ///                   emitModRMDecision() to.
12249884Ssheldonh  /// @param o2       - The output stream for the decision structure itself.
12349884Ssheldonh  /// @param i1       - The indent level to use with stream o1.
12449884Ssheldonh  /// @param i2       - The indent level to use with stream o2.
12549884Ssheldonh  /// @param decision - The OpcodeDecision to emit along with its subsidiary
12649884Ssheldonh  ///                    structures.
12749884Ssheldonh  void emitOpcodeDecision(raw_ostream &o1,
12849884Ssheldonh                          raw_ostream &o2,
12949884Ssheldonh                          uint32_t &i1,
13049884Ssheldonh                          uint32_t &i2,
13149884Ssheldonh                          OpcodeDecision &decision) const;
13249884Ssheldonh
13349884Ssheldonh  /// emitContextDecision - Emits a ContextDecision and all its subsidiary
13449884Ssheldonh  ///   Opcode and ModRMDecisions.  A ContextDecision is printed as:
13549884Ssheldonh  ///
13649884Ssheldonh  ///   struct ContextDecision NAME = {
13749884Ssheldonh  ///     { /* OpcodeDecisions */
13849884Ssheldonh  ///       /* IC */
13949884Ssheldonh  ///       { /* struct OpcodeDecision */
14049884Ssheldonh  ///         ...
14149884Ssheldonh  ///       },
1421556Srgrimes  ///       ...
1431556Srgrimes  ///     }
14449884Ssheldonh  ///   }
14549884Ssheldonh  ///
1461556Srgrimes  ///   NAME is the name of the ContextDecision (typically one of the four names
14776883Skris  ///   ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM,
14876883Skris  ///   THREEBYTEA6_SYM, and THREEBYTEA7_SYM from
14976883Skris  ///   X86DisassemblerDecoderCommon.h).
15076883Skris  ///   IC is one of the contexts in InstructionContext.  There is an opcode
15176883Skris  ///   decision for each possible context.
15276883Skris  ///   The OpcodeDecision structures are printed as described in the
15376883Skris  ///   documentation for emitOpcodeDecision.
15476883Skris  ///
15576883Skris  /// @param o1       - The output stream to print the ID tables generated by
15676883Skris  ///                   emitModRMDecision() to.
15776883Skris  /// @param o2       - The output stream to print the decision structure to.
15876883Skris  /// @param i1       - The indent level to use with stream o1.
15976883Skris  /// @param i2       - The indent level to use with stream o2.
16076883Skris  /// @param decision - The ContextDecision to emit along with its subsidiary
16176883Skris  ///                   structures.
16276883Skris  /// @param name     - The name for the ContextDecision.
16349884Ssheldonh  void emitContextDecision(raw_ostream &o1,
1641556Srgrimes                           raw_ostream &o2,
1651556Srgrimes                           uint32_t &i1,
1661556Srgrimes                           uint32_t &i2,
16749884Ssheldonh                           ContextDecision &decision,
1681556Srgrimes                           const char* name) const;
16949884Ssheldonh
17055179Ssheldonh  /// emitInstructionInfo - Prints the instruction specifier table, which has
1711556Srgrimes  ///   one entry for each instruction, and contains name and operand
17255179Ssheldonh  ///   information.  This table is printed as:
17355179Ssheldonh  ///
17455179Ssheldonh  ///   struct InstructionSpecifier CONTEXTS_SYM[k] = {
17555179Ssheldonh  ///     {
17655179Ssheldonh  ///       /* nnnn */
1771556Srgrimes  ///       "MNEMONIC",
1781556Srgrimes  ///       0xnn,
1791556Srgrimes  ///       {
1801556Srgrimes  ///         {
1811556Srgrimes  ///           ENCODING,
18250302Sgreen  ///           TYPE
18350087Sgreen  ///         },
18450087Sgreen  ///         ...
18550087Sgreen  ///       }
18649884Ssheldonh  ///     },
18749884Ssheldonh  ///   };
1881556Srgrimes  ///
18949884Ssheldonh  ///   k is the total number of instructions.
19049884Ssheldonh  ///   nnnn is the ID of the current instruction (0-based).  This table
19149884Ssheldonh  ///   includes entries for non-instructions like PHINODE.
19249884Ssheldonh  ///   0xnn is the lowest possible opcode for the current instruction, used for
1931556Srgrimes  ///   AddRegFrm instructions to compute the operand's value.
1941556Srgrimes  ///   ENCODING and TYPE describe the encoding and type for a single operand.
19549884Ssheldonh  ///
19649884Ssheldonh  /// @param o  - The output stream to which the instruction table should be
19749884Ssheldonh  ///             written.
19849884Ssheldonh  /// @param i  - The indent level for use with the stream.
1991556Srgrimes  void emitInstructionInfo(raw_ostream &o, uint32_t &i) const;
2001556Srgrimes
20149884Ssheldonh  /// emitContextTable - Prints the table that is used to translate from an
20249884Ssheldonh  ///   instruction attribute mask to an instruction context.  This table is
20349884Ssheldonh  ///   printed as:
20449884Ssheldonh  ///
2051556Srgrimes  ///   InstructionContext CONTEXTS_STR[256] = {
2061556Srgrimes  ///     IC, /* 0x00 */
20749884Ssheldonh  ///     ...
20849884Ssheldonh  ///   };
20949884Ssheldonh  ///
2101556Srgrimes  ///   IC is the context corresponding to the mask 0x00, and there are 256
21149884Ssheldonh  ///   possible masks.
2121556Srgrimes  ///
21349884Ssheldonh  /// @param o  - The output stream to which the context table should be written.
21449884Ssheldonh  /// @param i  - The indent level for use with the stream.
21549884Ssheldonh  void emitContextTable(raw_ostream &o, uint32_t &i) const;
21649884Ssheldonh
21749884Ssheldonh  /// emitContextDecisions - Prints all four ContextDecision structures using
21849884Ssheldonh  ///   emitContextDecision().
2194171Sache  ///
22049884Ssheldonh  /// @param o1 - The output stream to print the ID tables generated by
22149884Ssheldonh  ///             emitModRMDecision() to.
22249884Ssheldonh  /// @param o2 - The output stream to print the decision structures to.
22349884Ssheldonh  /// @param i1 - The indent level to use with stream o1.
22449884Ssheldonh  /// @param i2 - The indent level to use with stream o2.
2251556Srgrimes  void emitContextDecisions(raw_ostream &o1,
22649884Ssheldonh                            raw_ostream &o2,
22749884Ssheldonh                            uint32_t &i1,
22849884Ssheldonh                            uint32_t &i2) const;
22949884Ssheldonh
23049884Ssheldonh  /// setTableFields - Uses a ModRMFilter to set the appropriate entries in a
2311556Srgrimes  ///   ModRMDecision to refer to a particular instruction ID.
2321556Srgrimes  ///
2331556Srgrimes  /// @param decision - The ModRMDecision to populate.
23449884Ssheldonh  /// @param filter   - The filter to use in deciding which entries to populate.
23549884Ssheldonh  /// @param uid      - The unique ID to set matching entries to.
2361556Srgrimes  /// @param opcode   - The opcode of the instruction, for error reporting.
23749884Ssheldonh  void setTableFields(ModRMDecision &decision,
23849884Ssheldonh                      const ModRMFilter &filter,
23949884Ssheldonh                      InstrUID uid,
2401556Srgrimes                      uint8_t opcode);
2411556Srgrimespublic:
2421556Srgrimes  /// Constructor - Allocates space for the class decisions and clears them.
24349884Ssheldonh  DisassemblerTables();
24449884Ssheldonh
2451556Srgrimes  ~DisassemblerTables();
24649884Ssheldonh
24749884Ssheldonh  /// emit - Emits the instruction table, context table, and class decisions.
2481556Srgrimes  ///
24949884Ssheldonh  /// @param o  - The output stream to print the tables to.
25049884Ssheldonh  void emit(raw_ostream &o) const;
25149884Ssheldonh
25249884Ssheldonh  /// setTableFields - Uses the opcode type, instruction context, opcode, and a
25349884Ssheldonh  ///   ModRMFilter as criteria to set a particular set of entries in the
25449884Ssheldonh  ///   decode tables to point to a specific uid.
25549884Ssheldonh  ///
25649884Ssheldonh  /// @param type         - The opcode type (ONEBYTE, TWOBYTE, etc.)
25749884Ssheldonh  /// @param insnContext  - The context to use (IC, IC_64BIT, etc.)
25849884Ssheldonh  /// @param opcode       - The last byte of the opcode (not counting any escape
25949884Ssheldonh  ///                       or extended opcodes).
26049884Ssheldonh  /// @param filter       - The ModRMFilter that decides which ModR/M byte values
26149884Ssheldonh  ///                       correspond to the desired instruction.
26249884Ssheldonh  /// @param uid          - The unique ID of the instruction.
26349884Ssheldonh  void setTableFields(OpcodeType type,
26449884Ssheldonh                      InstructionContext insnContext,
26549884Ssheldonh                      uint8_t opcode,
26649884Ssheldonh                      const ModRMFilter &filter,
26749884Ssheldonh                      InstrUID uid);
26849884Ssheldonh
26949884Ssheldonh  /// specForUID - Returns the instruction specifier for a given unique
27049884Ssheldonh  ///   instruction ID.  Used when resolving collisions.
27149884Ssheldonh  ///
27249884Ssheldonh  /// @param uid  - The unique ID of the instruction.
27349884Ssheldonh  /// @return     - A reference to the instruction specifier.
2741556Srgrimes  InstructionSpecifier& specForUID(InstrUID uid) {
27549884Ssheldonh    if (uid >= InstructionSpecifiers.size())
27649884Ssheldonh      InstructionSpecifiers.resize(uid + 1);
27749884Ssheldonh
27849884Ssheldonh    return InstructionSpecifiers[uid];
27949884Ssheldonh  }
2801556Srgrimes
2811556Srgrimes  // hasConflicts - Reports whether there were primary decode conflicts
2821556Srgrimes  //   from any instructions added to the tables.
28349884Ssheldonh  // @return  - true if there were; false otherwise.
2841556Srgrimes
28549884Ssheldonh  bool hasConflicts() {
28649884Ssheldonh    return HasConflicts;
2871556Srgrimes  }
28849884Ssheldonh};
28949884Ssheldonh
29049884Ssheldonh} // namespace X86Disassembler
2911556Srgrimes
29249884Ssheldonh} // namespace llvm
29349884Ssheldonh
29449884Ssheldonh#endif
29549884Ssheldonh