LLVM для пользовательской цели - вылетает Disaeembly после добавления расширения вектора - PullRequest
0 голосов
/ 12 марта 2019

В качестве упражнения для оценки гибкости LLVM и RISC-V для поддержки разработки процессоров по обычному заказу я попытался добавить векторный регистровый файл в порт LowRISC RISCV LLVM. Я могу получить простую инструкцию добавления вектора для компиляции из ассемблера. Тем не менее, когда я пытаюсь выполнить тест туда и обратно (ассемблер + дизассемблер), llvm-objdump вылетает с исключением при попытке разобрать операнды инструкции vadd.

Вывод llvm-objdump:

> ./bin/llvm-mc rv32v-valid.s -triple=riscv32 -mattr=+m -filetype=obj |
> ./bin/llvm-objdump -mattr=+m -riscv-no-aliases -d -
> 
> <stdin>:  file format ELF32-riscv
> 
> Disassembly of section .text: .text:
>        0: 0b 80 20 02     vadd    llvm-objdump: /srv/workspaces/smutz/llvm-riscv/llvm/include/llvm/ADT/SmallVector.h:154:
> const_reference llvm::SmallVectorTemplateCommon<llvm::MCOperand,
> void>::operator[](size_type) const [T = llvm::MCOperand]: Assertion
> `idx < size()' failed.
> #0 0x00007f9c85945d4c llvm::sys::PrintStackTrace(llvm::raw_ostream&) /srv/workspaces/smutz/llvm-riscv/llvm/lib/Support/Unix/Signals.inc:398:0
> #1 0x00007f9c85945ef9 PrintStackTraceSignalHandler(void*) /srv/workspaces/smutz/llvm-riscv/llvm/lib/Support/Unix/Signals.inc:462:0
> #2 0x00007f9c85944433 llvm::sys::RunSignalHandlers() /srv/workspaces/smutz/llvm-riscv/llvm/lib/Support/Signals.cpp:50:0
> #3 0x00007f9c8594658f SignalHandler(int) /srv/workspaces/smutz/llvm-riscv/llvm/lib/Support/Unix/Signals.inc:252:0
> #4 0x00007f9c852ac330 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
> #5 0x00007f9c846e9c37 gsignal /build/eglibc-ripdx6/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
> #6 0x00007f9c846ed028 abort /build/eglibc-ripdx6/eglibc-2.19/stdlib/abort.c:91:0
> #7 0x00007f9c846e2bf6 __assert_fail_base /build/eglibc-ripdx6/eglibc-2.19/assert/assert.c:92:0
> #8 0x00007f9c846e2ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
> #9 0x00007f9c88ea84c1 llvm::SmallVectorTemplateCommon<llvm::MCOperand, void>::operator[](unsigned long) const
> /srv/workspaces/smutz/llvm-riscv/llvm/include/llvm/ADT/SmallVector.h:155:0
> #10 0x00007f9c88ea84c1 llvm::MCInst::getOperand(unsigned int) const /srv/workspaces/smutz/llvm-riscv/llvm/include/llvm/MC/MCInst.h:180:0
> #11 0x00007f9c88ea0208 llvm::RISCVInstPrinter::printOperand(llvm::MCInst const*, unsigned
> int, llvm::MCSubtargetInfo const&, llvm::raw_ostream&, char const*)
> /srv/workspaces/smutz/llvm-riscv/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp:54:0
> #12 0x00007f9c88e9fd4c llvm::RISCVInstPrinter::printInstruction(llvm::MCInst const*,
> llvm::MCSubtargetInfo const&, llvm::raw_ostream&)
> /srv/workspaces/smutz/llvm-riscv/build/lib/Target/RISCV/RISCVGenAsmWriter.inc:1089:0
> #13 0x00007f9c88ea7ef7 llvm::RISCVInstPrinter::printInst(llvm::MCInst const*, llvm::raw_ostream&, llvm::StringRef, llvm::MCSubtargetInfo
> const&)
> /srv/workspaces/smutz/llvm-riscv/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp:43:0
> #14 0x0000000000420c14 (anonymous namespace)::PrettyPrinter::printInst(llvm::MCInstPrinter&,
> llvm::MCInst const*, llvm::ArrayRef<unsigned char>, unsigned long,
> llvm::raw_ostream&, llvm::StringRef, llvm::MCSubtargetInfo const&,
> (anonymous namespace)::SourcePrinter*)
> /srv/workspaces/smutz/llvm-riscv/llvm/tools/llvm-objdump/llvm-objdump.cpp:514:0
> #15 0x0000000000425125 DisassembleObject(llvm::object::ObjectFile const*, bool)
> /srv/workspaces/smutz/llvm-riscv/llvm/tools/llvm-objdump/llvm-objdump.cpp:1604:0
> #16 0x000000000042126c DumpObject(llvm::object::ObjectFile*, llvm::object::Archive const*)
> /srv/workspaces/smutz/llvm-riscv/llvm/tools/llvm-objdump/llvm-objdump.cpp:2055:0
> #17 0x0000000000420893 DumpInput(llvm::StringRef) /srv/workspaces/smutz/llvm-riscv/llvm/tools/llvm-objdump/llvm-objdump.cpp:2146:0
> #18 0x0000000000433122 void (*std::for_each<__gnu_cxx::__normal_iterator<std::string*,
> std::vector<std::string, std::allocator<std::string> > >, void
> (*)(llvm::StringRef)>(__gnu_cxx::__normal_iterator<std::string*,
> std::vector<std::string, std::allocator<std::string> > >,
> __gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string> > >, void
> (*)(llvm::StringRef)))(llvm::StringRef)
> /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:4417:0
> #19 0x000000000043304b void (*llvm::for_each<llvm::cl::list<std::string, bool,
> llvm::cl::parser<std::string> >&, void
> (*)(llvm::StringRef)>(llvm::cl::list<std::string, bool,
> llvm::cl::parser<std::string> >&, void
> (*)(llvm::StringRef)))(llvm::StringRef)
> /srv/workspaces/smutz/llvm-riscv/llvm/include/llvm/ADT/STLExtras.h:808:0
> #20 0x0000000000420732 main /srv/workspaces/smutz/llvm-riscv/llvm/tools/llvm-objdump/llvm-objdump.cpp:2208:0
> #21 0x00007f9c846d4f45 __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:321:0
> #22 0x000000000041cb2e _start (./bin/llvm-objdump+0x41cb2e) Stack dump:
> 0.    Program arguments: ./bin/llvm-objdump -mattr=+m -riscv-no-aliases -d -  Aborted

Биты, которые я добавил для поддержки вектора:

In lib/Target/RISCV/RISCVRegisterInfo.td
// Vector registers
let RegAltNameIndices = [ABIRegAltName] in {
  def V0  : RISCVReg<0, "v0",  ["v0"]>,  DwarfRegNum<[64]>;
  def V1  : RISCVReg<1, "v1",  ["v1"]>,  DwarfRegNum<[65]>;
  def V2  : RISCVReg<2, "v2",  ["v2"]>,  DwarfRegNum<[66]>;
  def V3  : RISCVReg<3, "v3",  ["v3"]>,  DwarfRegNum<[67]>;
  def V4  : RISCVReg<4, "v4",  ["v4"]>,  DwarfRegNum<[68]>;
  def V5  : RISCVReg<5, "v5",  ["v5"]>,  DwarfRegNum<[69]>;
  def V6  : RISCVReg<6, "v6",  ["v6"]>,  DwarfRegNum<[70]>;
  def V7  : RISCVReg<7, "v7",  ["v7"]>,  DwarfRegNum<[71]>;
  def V8  : RISCVReg<8, "v8",  ["v8"]>,  DwarfRegNum<[72]>;
  def V9  : RISCVReg<9, "v9",  ["v9"]>,  DwarfRegNum<[73]>;
  def V10 : RISCVReg<10,"v10", ["v10"]>, DwarfRegNum<[74]>;
  def V11 : RISCVReg<11,"v11", ["v11"]>, DwarfRegNum<[75]>;
  def V12 : RISCVReg<12,"v12", ["v12"]>, DwarfRegNum<[76]>;
  def V13 : RISCVReg<13,"v13", ["v13"]>, DwarfRegNum<[77]>;
  def V14 : RISCVReg<14,"v14", ["v14"]>, DwarfRegNum<[76]>;
  def V15 : RISCVReg<15,"v15", ["v15"]>, DwarfRegNum<[79]>;
  def V16 : RISCVReg<16, "v16",  ["v16"]>,  DwarfRegNum<[80]>;
  def V17 : RISCVReg<17, "v17",  ["v17"]>,  DwarfRegNum<[81]>;
  def V18 : RISCVReg<18, "v18",  ["v18"]>,  DwarfRegNum<[82]>;
  def V19 : RISCVReg<19, "v19",  ["v19"]>,  DwarfRegNum<[83]>;
  def V20 : RISCVReg<20, "v20",  ["v20"]>,  DwarfRegNum<[84]>;
  def V21 : RISCVReg<21, "v21",  ["v21"]>,  DwarfRegNum<[85]>;
  def V22 : RISCVReg<22, "v22",  ["v22"]>,  DwarfRegNum<[86]>;
  def V23 : RISCVReg<23, "v23",  ["v23"]>,  DwarfRegNum<[87]>;
  def V24 : RISCVReg<24, "v24",  ["v24"]>,  DwarfRegNum<[88]>;
  def V25 : RISCVReg<25, "v25",  ["v25"]>,  DwarfRegNum<[89]>;
  def V26 : RISCVReg<26, "v26",  ["v26"]>,  DwarfRegNum<[90]>;
  def V27 : RISCVReg<27, "v27",  ["v27"]>,  DwarfRegNum<[91]>;
  def V28 : RISCVReg<28, "v28",  ["v28"]>,  DwarfRegNum<[92]>;
  def V29 : RISCVReg<29, "v29",  ["v29"]>,  DwarfRegNum<[93]>;
  def V30 : RISCVReg<30, "v30",  ["v30"]>,  DwarfRegNum<[94]>;
  def V31 : RISCVReg<31, "v31",  ["v31"]>,  DwarfRegNum<[95]>;
}

// The order of registers represents the preferred allocation sequence,
// meaning caller-save regs are listed before callee-save.
def VR : RegisterClass<"RISCV", [v8i32], 256, (add
    (sequence "V%u", 0, 31)
)>;

И

In lib/Target/RISCV/RISCVRegisterInfo.td
def OPC_OP_V        : RISCVOpcode<0b0001011>;

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class V_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
    : RVInstR<funct7, funct3, OPC_OP_V, (outs VR:$vd), (ins VR:$v1, VR:$v2),
              opcodestr, "$vd, $v1, $v2">;

def VADD     : V_rr<0b0000001, 0b000, "vadd">;

Когда я смотрю на код для RISCV, в lib / Target / RISCV / Disassembler / RISCVDisassembler.cpp объявлена ​​функция, называемая DecodeGPRRegisterClass () и аналогичная для регистров FPR, которые, похоже, играют роль в разборке. Эти функции вызываются из кода, сгенерированного TableGen. Я добавил функцию для моего нового класса векторных регистров. Однако к нему не генерируются вызовы, что не соответствует ожиданиям.

Я посмотрел вокруг и просмотрел патчи, используемые для реализации поддержки RISCV, но я пока не смог понять, что я упустил, чтобы заставить дизассемблер работать с новыми классами регистров. Я был бы очень признателен за некоторые советы.

...