brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.5 KiB · 52f9538 Raw
401 lines · c
1//===- X86RecognizableInstr.h - Disassembler instruction spec ---*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is part of the X86 Disassembler Emitter.10// It contains the interface of a single recognizable instruction.11// Documentation for the disassembler emitter in general can be found in12//  X86DisassemblerEmitter.h.13//14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_UTILS_TABLEGEN_X86RECOGNIZABLEINSTR_H17#define LLVM_UTILS_TABLEGEN_X86RECOGNIZABLEINSTR_H18 19#include "Common/CodeGenInstruction.h"20#include "llvm/Support/X86DisassemblerDecoderCommon.h"21#include <cstdint>22#include <string>23#include <vector>24 25namespace llvm {26class Record;27#define X86_INSTR_MRM_MAPPING                                                  \28  MAP(C0, 64)                                                                  \29  MAP(C1, 65)                                                                  \30  MAP(C2, 66)                                                                  \31  MAP(C3, 67)                                                                  \32  MAP(C4, 68)                                                                  \33  MAP(C5, 69)                                                                  \34  MAP(C6, 70)                                                                  \35  MAP(C7, 71)                                                                  \36  MAP(C8, 72)                                                                  \37  MAP(C9, 73)                                                                  \38  MAP(CA, 74)                                                                  \39  MAP(CB, 75)                                                                  \40  MAP(CC, 76)                                                                  \41  MAP(CD, 77)                                                                  \42  MAP(CE, 78)                                                                  \43  MAP(CF, 79)                                                                  \44  MAP(D0, 80)                                                                  \45  MAP(D1, 81)                                                                  \46  MAP(D2, 82)                                                                  \47  MAP(D3, 83)                                                                  \48  MAP(D4, 84)                                                                  \49  MAP(D5, 85)                                                                  \50  MAP(D6, 86)                                                                  \51  MAP(D7, 87)                                                                  \52  MAP(D8, 88)                                                                  \53  MAP(D9, 89)                                                                  \54  MAP(DA, 90)                                                                  \55  MAP(DB, 91)                                                                  \56  MAP(DC, 92)                                                                  \57  MAP(DD, 93)                                                                  \58  MAP(DE, 94)                                                                  \59  MAP(DF, 95)                                                                  \60  MAP(E0, 96)                                                                  \61  MAP(E1, 97)                                                                  \62  MAP(E2, 98)                                                                  \63  MAP(E3, 99)                                                                  \64  MAP(E4, 100)                                                                 \65  MAP(E5, 101)                                                                 \66  MAP(E6, 102)                                                                 \67  MAP(E7, 103)                                                                 \68  MAP(E8, 104)                                                                 \69  MAP(E9, 105)                                                                 \70  MAP(EA, 106)                                                                 \71  MAP(EB, 107)                                                                 \72  MAP(EC, 108)                                                                 \73  MAP(ED, 109)                                                                 \74  MAP(EE, 110)                                                                 \75  MAP(EF, 111)                                                                 \76  MAP(F0, 112)                                                                 \77  MAP(F1, 113)                                                                 \78  MAP(F2, 114)                                                                 \79  MAP(F3, 115)                                                                 \80  MAP(F4, 116)                                                                 \81  MAP(F5, 117)                                                                 \82  MAP(F6, 118)                                                                 \83  MAP(F7, 119)                                                                 \84  MAP(F8, 120)                                                                 \85  MAP(F9, 121)                                                                 \86  MAP(FA, 122)                                                                 \87  MAP(FB, 123)                                                                 \88  MAP(FC, 124)                                                                 \89  MAP(FD, 125)                                                                 \90  MAP(FE, 126)                                                                 \91  MAP(FF, 127)92 93// A clone of X86 since we can't depend on something that is generated.94namespace X86Local {95enum {96  Pseudo = 0,97  RawFrm = 1,98  AddRegFrm = 2,99  RawFrmMemOffs = 3,100  RawFrmSrc = 4,101  RawFrmDst = 5,102  RawFrmDstSrc = 6,103  RawFrmImm8 = 7,104  RawFrmImm16 = 8,105  AddCCFrm = 9,106  PrefixByte = 10,107  MRMDestRegCC = 18,108  MRMDestMemCC = 19,109  MRMDestMem4VOp3CC = 20,110  MRMr0 = 21,111  MRMSrcMemFSIB = 22,112  MRMDestMemFSIB = 23,113  MRMDestMem = 24,114  MRMSrcMem = 25,115  MRMSrcMem4VOp3 = 26,116  MRMSrcMemOp4 = 27,117  MRMSrcMemCC = 28,118  MRMXmCC = 30,119  MRMXm = 31,120  MRM0m = 32,121  MRM1m = 33,122  MRM2m = 34,123  MRM3m = 35,124  MRM4m = 36,125  MRM5m = 37,126  MRM6m = 38,127  MRM7m = 39,128  MRMDestReg = 40,129  MRMSrcReg = 41,130  MRMSrcReg4VOp3 = 42,131  MRMSrcRegOp4 = 43,132  MRMSrcRegCC = 44,133  MRMXrCC = 46,134  MRMXr = 47,135  MRM0r = 48,136  MRM1r = 49,137  MRM2r = 50,138  MRM3r = 51,139  MRM4r = 52,140  MRM5r = 53,141  MRM6r = 54,142  MRM7r = 55,143  MRM0X = 56,144  MRM1X = 57,145  MRM2X = 58,146  MRM3X = 59,147  MRM4X = 60,148  MRM5X = 61,149  MRM6X = 62,150  MRM7X = 63,151#define MAP(from, to) MRM_##from = to,152  X86_INSTR_MRM_MAPPING153#undef MAP154};155 156enum {157  OB = 0,158  TB = 1,159  T8 = 2,160  TA = 3,161  XOP8 = 4,162  XOP9 = 5,163  XOPA = 6,164  ThreeDNow = 7,165  T_MAP4 = 8,166  T_MAP5 = 9,167  T_MAP6 = 10,168  T_MAP7 = 11169};170 171enum { PD = 1, XS = 2, XD = 3, PS = 4 };172enum { VEX = 1, XOP = 2, EVEX = 3 };173enum { OpSize16 = 1, OpSize32 = 2 };174enum { AdSize16 = 1, AdSize32 = 2, AdSize64 = 3 };175enum { ExplicitREX2 = 1, ExplicitEVEX = 3 };176} // namespace X86Local177 178namespace X86Disassembler {179class DisassemblerTables;180struct InstructionSpecifier;181 182/// Extract common fields of a single X86 instruction from a CodeGenInstruction183struct RecognizableInstrBase {184  /// The OpPrefix field from the record185  uint8_t OpPrefix;186  /// The OpMap field from the record187  uint8_t OpMap;188  /// The opcode field from the record; this is the opcode used in the Intel189  /// encoding and therefore distinct from the UID190  uint8_t Opcode;191  /// The form field from the record192  uint8_t Form;193  // The encoding field from the record194  uint8_t Encoding;195  /// The OpSize field from the record196  uint8_t OpSize;197  /// The AdSize field from the record198  uint8_t AdSize;199  /// The hasREX_W field from the record200  bool HasREX_W;201  /// The hasVEX_4V field from the record202  bool HasVEX_4V;203  /// The IgnoresW field from the record204  bool IgnoresW;205  /// The hasVEX_L field from the record206  bool HasVEX_L;207  /// The ignoreVEX_L field from the record208  bool IgnoresVEX_L;209  /// The hasEVEX_L2Prefix field from the record210  bool HasEVEX_L2;211  /// The hasEVEX_K field from the record212  bool HasEVEX_K;213  /// The hasEVEX_KZ field from the record214  bool HasEVEX_KZ;215  /// The hasEVEX_B field from the record216  bool HasEVEX_B;217  /// The hasEVEX_U field from the record218  bool HasEVEX_U;219  /// The hasEVEX_NF field from the record220  bool HasEVEX_NF;221  /// The hasTwoConditionalOps field from the record222  bool HasTwoConditionalOps;223  /// Indicates that the instruction uses the L and L' fields for RC.224  bool EncodeRC;225  /// The isCodeGenOnly field from the record226  bool IsCodeGenOnly;227  /// The isAsmParserOnly field from the record228  bool IsAsmParserOnly;229  /// The ForceDisassemble field from the record230  bool ForceDisassemble;231  // The CD8_Scale field from the record232  uint8_t CD8_Scale;233  /// If explicitOpPrefix field from the record equals ExplicitREX2234  bool ExplicitREX2Prefix;235  /// \param insn The CodeGenInstruction to extract information from.236  RecognizableInstrBase(const CodeGenInstruction &insn);237  /// \returns true if this instruction should be emitted238  bool shouldBeEmitted() const;239};240 241/// RecognizableInstr - Encapsulates all information required to decode a single242///   instruction, as extracted from the LLVM instruction tables.  Has methods243///   to interpret the information available in the LLVM tables, and to emit the244///   instruction into DisassemblerTables.245class RecognizableInstr : public RecognizableInstrBase {246private:247  /// The record from the .td files corresponding to this instruction248  const Record *Rec;249  /// The instruction name as listed in the tables250  std::string Name;251  // Whether the instruction has the predicate "In32BitMode"252  bool Is32Bit;253  // Whether the instruction has the predicate "In64BitMode"254  bool Is64Bit;255  /// The operands of the instruction, as listed in the CodeGenInstruction.256  /// They are not one-to-one with operands listed in the MCInst; for example,257  /// memory operands expand to 5 operands in the MCInst258  const std::vector<CGIOperandList::OperandInfo> *Operands;259 260  /// The opcode of the instruction, as used in an MCInst261  InstrUID UID;262  /// The description of the instruction that is emitted into the instruction263  /// info table264  InstructionSpecifier *Spec;265 266  /// insnContext - Returns the primary context in which the instruction is267  ///   valid.268  ///269  /// @return - The context in which the instruction is valid.270  InstructionContext insnContext() const;271 272  /// typeFromString - Translates an operand type from the string provided in273  ///   the LLVM tables to an OperandType for use in the operand specifier.274  ///275  /// @param s              - The string, as extracted by calling Rec->getName()276  ///                         on a CodeGenInstruction::OperandInfo.277  /// @param hasREX_W - Indicates whether the instruction has a REX.W278  ///                         prefix.  If it does, 32-bit register operands stay279  ///                         32-bit regardless of the operand size.280  /// @param OpSize           Indicates the operand size of the instruction.281  ///                         If register size does not match OpSize, then282  ///                         register sizes keep their size.283  /// @return               - The operand's type.284  static OperandType typeFromString(StringRef Str, bool hasREX_W,285                                    uint8_t OpSize);286 287  /// immediateEncodingFromString - Translates an immediate encoding from the288  ///   string provided in the LLVM tables to an OperandEncoding for use in289  ///   the operand specifier.290  ///291  /// @param s       - See typeFromString().292  /// @param OpSize  - Indicates whether this is an OpSize16 instruction.293  ///                  If it is not, then 16-bit immediate operands stay 16-bit.294  /// @return        - The operand's encoding.295  static OperandEncoding immediateEncodingFromString(StringRef Str,296                                                     uint8_t OpSize);297 298  /// rmRegisterEncodingFromString - Like immediateEncodingFromString, but299  ///   handles operands that are in the REG field of the ModR/M byte.300  static OperandEncoding rmRegisterEncodingFromString(StringRef Str,301                                                      uint8_t OpSize);302 303  /// rmRegisterEncodingFromString - Like immediateEncodingFromString, but304  ///   handles operands that are in the REG field of the ModR/M byte.305  static OperandEncoding roRegisterEncodingFromString(StringRef Str,306                                                      uint8_t OpSize);307  static OperandEncoding memoryEncodingFromString(StringRef Str,308                                                  uint8_t OpSize);309  static OperandEncoding relocationEncodingFromString(StringRef Str,310                                                      uint8_t OpSize);311  static OperandEncoding opcodeModifierEncodingFromString(StringRef Str,312                                                          uint8_t OpSize);313  static OperandEncoding vvvvRegisterEncodingFromString(StringRef Str,314                                                        uint8_t OpSize);315  static OperandEncoding writemaskRegisterEncodingFromString(StringRef Str,316                                                             uint8_t OpSize);317 318  /// Adjust the encoding type for an operand based on the instruction.319  void adjustOperandEncoding(OperandEncoding &encoding);320 321  /// handleOperand - Converts a single operand from the LLVM table format to322  ///   the emitted table format, handling any duplicate operands it encounters323  ///   and then one non-duplicate.324  ///325  /// @param optional             - Determines whether to assert that the326  ///                               operand exists.327  /// @param operandIndex         - The index into the generated operand table.328  ///                               Incremented by this function one or more329  ///                               times to reflect possible duplicate330  ///                               operands).331  /// @param physicalOperandIndex - The index of the current operand into the332  ///                               set of non-duplicate ('physical') operands.333  ///                               Incremented by this function once.334  /// @param numPhysicalOperands  - The number of non-duplicate operands in the335  ///                               instructions.336  /// @param operandMapping       - The operand mapping, which has an entry for337  ///                               each operand that indicates whether it is a338  ///                               duplicate, and of what.339  using EncodingFn =340      llvm::function_ref<OperandEncoding(StringRef s, uint8_t OpSize)>;341  void handleOperand(bool optional, unsigned &operandIndex,342                     unsigned &physicalOperandIndex,343                     unsigned numPhysicalOperands,344                     const unsigned *operandMapping,345                     EncodingFn encodingFromString);346 347  /// emitInstructionSpecifier - Loads the instruction specifier for the current348  ///   instruction into a DisassemblerTables.349  ///350  void emitInstructionSpecifier();351 352  /// emitDecodePath - Populates the proper fields in the decode tables353  ///   corresponding to the decode paths for this instruction.354  ///355  /// \param tables The DisassemblerTables to populate with the decode356  ///               decode information for the current instruction.357  void emitDecodePath(DisassemblerTables &tables) const;358 359public:360  /// Constructor - Initializes a RecognizableInstr with the appropriate fields361  ///   from a CodeGenInstruction.362  ///363  /// \param tables The DisassemblerTables that the specifier will be added to.364  /// \param insn   The CodeGenInstruction to extract information from.365  /// \param uid    The unique ID of the current instruction.366  RecognizableInstr(DisassemblerTables &tables, const CodeGenInstruction &insn,367                    InstrUID uid);368  /// processInstr - Accepts a CodeGenInstruction and loads decode information369  ///   for it into a DisassemblerTables if appropriate.370  ///371  /// \param tables The DiassemblerTables to be populated with decode372  ///               information.373  /// \param insn   The CodeGenInstruction to be used as a source for this374  ///               information.375  /// \param uid    The unique ID of the instruction.376  static void processInstr(DisassemblerTables &tables,377                           const CodeGenInstruction &insn, InstrUID uid);378};379 380std::string getMnemonic(const CodeGenInstruction *I, unsigned Variant);381bool isRegisterOperand(const Record *Rec);382bool isMemoryOperand(const Record *Rec);383bool isImmediateOperand(const Record *Rec);384unsigned getRegOperandSize(const Record *RegRec);385unsigned getMemOperandSize(const Record *MemRec);386 387/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.388///   Useful for switch statements and the like.389///390/// @param B - A pointer to the BitsInit to be decoded.391/// @return  - The field, with the first bit in the BitsInit as the lowest392///            order bit.393inline uint8_t byteFromBitsInit(const BitsInit *B) {394  assert(B->getNumBits() <= 8 && "Field is too large for uint8_t!");395  return static_cast<uint8_t>(*B->convertInitializerToInt());396}397 398} // namespace X86Disassembler399} // namespace llvm400#endif401