[PATCH] D155329: [TableGen][CodeEmitterGen] Add support for querying operand bit offsets

Ilya Leoshkevich via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 17 08:56:57 PDT 2023


iii added a comment.

Right now there doesn't seem to be a generic way to get the instruction endianness.
The best example is ARM:

  ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
                  const MCInstrInfo *MCII)
      : MCDisassembler(STI, Ctx), MCII(MCII) {
    InstructionEndianness = STI.hasFeature(ARM::ModeBigEndianInstructions)
                                ? llvm::support::big
                                : llvm::support::little;

where it's separate from data endianness and is not available to TableGen.
Even though it's used only for disassembly, it demonstrates the level of flexibility that may be requred.

So I wonder if it would be acceptable to pass endianness as a parameter to `getOperandBitOffset()` like this?

  --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
  +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
  @@ -55,6 +55,7 @@ private:
                                    SmallVectorImpl<MCFixup> &Fixups,
                                    const MCSubtargetInfo &STI) const;
     uint32_t getOperandBitOffset(const MCInst &MI, unsigned OpNum,
  +                               bool IsLittleEndian,
                                  const MCSubtargetInfo &STI) const;
   
     // Called by the TableGen code to get the binary encoding of operand
  @@ -174,7 +175,7 @@ uint64_t SystemZMCCodeEmitter::getDispOpValue(const MCInst &MI, unsigned OpNum,
     if (MO.isImm())
       return static_cast<uint64_t>(MO.getImm());
     if (MO.isExpr()) {
  -    uint32_t BitOffset = getOperandBitOffset(MI, OpNum, STI);
  +    uint32_t BitOffset = getOperandBitOffset(MI, OpNum, false, STI);
       Fixups.push_back(MCFixup::create(BitOffset >> 3, MO.getExpr(),
                                        (MCFixupKind)Kind, MI.getLoc()));
       assert(Fixups.size() <= 2 && "More than two memory operands in MI?");
  diff --git a/llvm/utils/TableGen/CodeEmitterGen.cpp b/llvm/utils/TableGen/CodeEmitterGen.cpp
  index dcac1efb7132..ddca6f0a2a68 100644
  --- a/llvm/utils/TableGen/CodeEmitterGen.cpp
  +++ b/llvm/utils/TableGen/CodeEmitterGen.cpp
  @@ -211,12 +211,11 @@ bool CodeEmitterGen::addCodeToMergeInOperand(Record *R, BitsInit *BI,
       unsigned hiBit = loBit + N;
       unsigned loInstBit = beginInstBit - N + 1;
       if (!BitOffsetCaseEmitted) {
  -      unsigned bitOffset = Target.isLittleEndianEncoding()
  -                               ? beginInstBit
  -                               : BI->getNumBits() - beginInstBit - 1;
         BitOffsetCase += "      case " + utostr(OpIdx) + ":\n";
         BitOffsetCase += "        // op: " + VarName + "\n";
  -      BitOffsetCase += "        return " + utostr(bitOffset) + ";\n";
  +      BitOffsetCase += "        return IsLittleEndian ? " +
  +                       utostr(beginInstBit) + " : " +
  +                       utostr(BI->getNumBits() - beginInstBit - 1) + ";\n";
         BitOffsetCaseEmitted = true;
       }
       if (UseAPInt) {
  @@ -537,6 +536,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
         << "uint32_t " << Target.getName()
         << "MCCodeEmitter::getOperandBitOffset(const MCInst &MI,\n"
         << "    unsigned OpNum,\n"
  +      << "    bool IsLittleEndian,\n"
         << "    const MCSubtargetInfo &STI) const {\n"
         << "  switch (MI.getOpcode()) {\n";
       emitCaseMap(o, BitOffsetCaseMap);


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155329/new/

https://reviews.llvm.org/D155329



More information about the llvm-commits mailing list