FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

LLVMのバックエンドを作るための第一歩 (40. objdumpのサポート)

f:id:msyksphinz:20190425001356p:plain

現状、llvm-objdumpを実行すると以下のようになってしまう。これをサポートする。

% ./bin/llvm-objdump -d results/if_ctrl-O0_-march=mips_-relocation-model=static/if_ctrl.bc
./bin/llvm-objdump: error: 'results/if_ctrl-O0_-march=mips_-relocation-model=static/if_ctrl.bc': The file was not recognized as a valid object file
  • lib/Target/MYRISCVX/CMakeLists.txt
lib/Target/MYRISCVX/CMakeLists.txt
  • llvm-myriscvx/lib/Target/MYRISCVX/Disassembler/MYRISCVXDisassembler.cpp
/// MYRISCVXDisassembler - a disasembler class for MYRISCVX32.
class MYRISCVXDisassembler : public MYRISCVXDisassemblerBase {
 public:
  /// Constructor     - Initializes the disassembler.
  ///
  MYRISCVXDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
      : MYRISCVXDisassemblerBase(STI, Ctx, bigEndian) {
  }

  /// getInstruction - See MCDisassembler.
  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
                              ArrayRef<uint8_t> Bytes, uint64_t Address,
                              raw_ostream &VStream,
                              raw_ostream &CStream) const override;
};

} // end anonymous namespace
/// Read four bytes from the ArrayRef and return 32 bit word sorted
/// according to the given endianess
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
                                      uint64_t &Size, uint32_t &Insn,
                                      bool IsBigEndian) {
  // We want to read exactly 4 Bytes of data.
  if (Bytes.size() < 4) {
    Size = 0;
    return MCDisassembler::Fail;
  }

  if (IsBigEndian) {
    // Encoded as a big-endian 32-bit word in the stream.
    Insn = (Bytes[3] <<  0) |
        (Bytes[2] <<  8) |
        (Bytes[1] << 16) |
        (Bytes[0] << 24);
  }
  else {
    // Encoded as a small-endian 32-bit word in the stream.
    Insn = (Bytes[0] <<  0) |
        (Bytes[1] <<  8) |
        (Bytes[2] << 16) |
        (Bytes[3] << 24);
  }

  return MCDisassembler::Success;
}

DecodeStatus
MYRISCVXDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
                                     ArrayRef<uint8_t> Bytes,
                                     uint64_t Address,
                                     raw_ostream &VStream,
                                     raw_ostream &CStream) const {
  uint32_t Insn;

  DecodeStatus Result;

  Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian);

  if (Result == MCDisassembler::Fail)
    return MCDisassembler::Fail;

  // Calling the auto-generated decoder function.
  Result = decodeInstruction(DecoderTableMYRISCVX32, Instr, Insn, Address,
                             this, STI);
  if (Result != MCDisassembler::Fail) {
    Size = 4;
    return Result;
  }

  return MCDisassembler::Fail;
}
static DecodeStatus DecodeBranch12Target(MCInst &Inst,
                                         unsigned Insn,
                                         uint64_t Address,
                                         const void *Decoder) {
  int BranchOffset = SignExtend32<12>((fieldFromInstruction(Insn, 31, 1) << 12) |
                                      (fieldFromInstruction(Insn, 25, 6) <<  5) |
                                      (fieldFromInstruction(Insn,  8, 4) <<  1) |
                                      (fieldFromInstruction(Insn,  7, 1) << 11));
  Inst.addOperand(MCOperand::createImm(BranchOffset));
  return MCDisassembler::Success;
}

アセンブルを追加して、以下のようになった。

Disassembly of section .text:
0000000000000000 _Z11test_ifctrlv:
       0:       13 01 81 ff     addi    x11, x11, -8
       4:       13 05 00 00     addi    x6, zero, 0
       8:       23 22 a1 00     sw      x6, 4(x11)
       c:       03 25 41 00     lw      x6, 4(x11)
      10:       63 10 05 00     bne     x6, zero, 0
      14:       03 25 41 00     lw      x6, 4(x11)
      18:       13 05 15 00     addi    x6, x6, 1
      1c:       23 22 a1 00     sw      x6, 4(x11)

0000000000000020 $BB0_2:
      20:       03 25 41 00     lw      x6, 4(x11)
      24:       13 01 81 00     addi    x11, x11, 8
      28:       67 80 10 00     ret     x10