Index: tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/CMakeLists.txt =================================================================== --- tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/CMakeLists.txt +++ tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/CMakeLists.txt @@ -5,19 +5,25 @@ set(LLVM_OPTIONAL_SOURCES example_proto_to_asm.cpp proto_to_asm_main.cpp proto_to_asm_riscv.cpp proto_to_asm_riscv_fuzz_opnd_values.cpp) +set(LLVM_TARGET_DEFINITIONS ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/Target/RISCV/RISCV.td) +tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info -I ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/Target/RISCV) +tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info -I ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/Target/RISCV) +add_public_tablegen_target(RISCVTableGen) + + llvm_add_library(mcProtoToASM example_proto_to_asm.cpp - DEPENDS mcASMProto + DEPENDS mcASMProto RISCVTableGen LINK_LIBS mcASMProto ${PROTOBUF_LIBRARIES} ) llvm_add_library(mcRISCVProtoToASM proto_to_asm_riscv.cpp - DEPENDS mcRISCVASMProto + DEPENDS mcRISCVASMProto RISCVTableGen LINK_LIBS mcRISCVASMProto ${PROTOBUF_LIBRARIES} ) llvm_add_library(mcRISCVFuzzOpndValuesProtoToASM proto_to_asm_riscv_fuzz_opnd_values.cpp - DEPENDS mcRISCVFuzzOpndValuesASMProto + DEPENDS mcRISCVFuzzOpndValuesASMProto RISCVTableGen LINK_LIBS mcRISCVFuzzOpndValuesASMProto ${PROTOBUF_LIBRARIES} ) Index: tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/example_proto_to_asm.cpp =================================================================== --- tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/example_proto_to_asm.cpp +++ tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/example_proto_to_asm.cpp @@ -22,28 +22,82 @@ using namespace google::protobuf; -static void EmitAsm(std::ostream &OS, const EnumDescriptor *Enum, int Num) { - const EnumValueDescriptor *D = Enum->FindValueByNumber(Num); - std::string Msg = D->name(); - std::transform(Msg.begin(), Msg.end(), Msg.begin(), ::tolower); - OS << Msg; +namespace mc_proto_fuzzer { + +template +static void getMessageName(const T &X, std::string &Msg) { + const EnumDescriptor *D = X.ValueRange_descriptor(); + const EnumValueDescriptor *VD = D->FindValueByNumber(X.value()); + Msg = VD->name(); + std::transform(Msg.begin(), Msg.end(), Msg.begin(), ::toupper); +} +// --------------------------------- +// Emit MC Instruction +// --------------------------------- +#define EMIT_MC_INST +#ifdef EMIT_MC_INST +#include "riscv_support.h" + +template +static void EmitMCOpcode(std::ostream &OS, const T &X) { + std::string Msg; + getMessageName(X, Msg); + unsigned MCOpcode; + if (getMCOpcode(Msg, MCOpcode)) + OS << " #" << MCOpcode << ' ' << Msg; + else + OS << " #ERROR " << Msg; } -namespace mc_proto_fuzzer { +static void EmitMCOperand(std::ostream &OS, const Register &X) { + std::string Msg; + getMessageName(X, Msg); + unsigned MCReg; + OS << "\n# '; +} + +static void EmitMC(std::ostream &OS, const RTypeStatement &X) { + EmitMCOpcode(OS, X.opcode()); + // Directly handling RTypeOperands which has 3 operands. + auto Y = X.operands(); + EmitMCOperand(OS, Y.operand1()); + EmitMCOperand(OS, Y.operand2()); + EmitMCOperand(OS, Y.operand3()); +} + +static void EmitMC(std::ostream &OS, const AsmStatement &X) { + OS << "# \n"; +} + +#endif // EMIT_MC_INST + + +// --------------------------------- +// Emit Assembly Instruction +// --------------------------------- template -void Emit(std::ostream &OS, const T &X) { - const EnumDescriptor *ED = X.ValueRange_descriptor(); - EmitAsm(OS, ED, X.value()); +void EmitAsm(std::ostream &OS, const T &X) { + std::string Msg; + getMessageName(X, Msg); + std::transform(Msg.begin(), Msg.end(), Msg.begin(), ::tolower); + OS << Msg; } std::ostream &operator<<(std::ostream &OS, const Register &X) { - Emit(OS, X); + EmitAsm(OS, X); return OS; } std::ostream &operator<<(std::ostream &OS, const RTypeOpcode &X) { - Emit(OS, X); + EmitAsm(OS, X); return OS; } @@ -65,8 +119,12 @@ } std::ostream &operator<<(std::ostream &OS, const Assembly &X) { - for (auto &ST : X.statements()) + for (auto &ST : X.statements()) { OS << ST; +#ifdef EMIT_MC_INST + EmitMC(OS, ST); +#endif // EMIT_MC_INST + } return OS; } Index: tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/proto_to_asm_riscv.cpp =================================================================== --- tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/proto_to_asm_riscv.cpp +++ tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/proto_to_asm_riscv.cpp @@ -31,22 +31,217 @@ using namespace google::protobuf; -static void EmitAsm(std::ostream &OS, const EnumDescriptor * Enum, - int Num, bool SkipReplace = false) { - const EnumValueDescriptor * D = Enum->FindValueByNumber(Num); - std::string Msg = D->name(); +namespace mc_proto_fuzzer { + +template +static void getMessageName(const T &X, std::string &Msg) { + const EnumDescriptor *D = X.ValueRange_descriptor(); + const EnumValueDescriptor *VD = D->FindValueByNumber(X.value()); + Msg = VD->name(); + std::transform(Msg.begin(), Msg.end(), Msg.begin(), ::toupper); +} + +// --------------------------------- +// Emit MC Instruction +// --------------------------------- +#define EMIT_MC_INST +#ifdef EMIT_MC_INST +#include "riscv_support.h" + +template +static void EmitMCOpcode(std::ostream &OS, const T &X) { + std::string Msg; + getMessageName(X, Msg); + unsigned MCOpcode; + if (getMCOpcode(Msg, MCOpcode)) + OS << " #" << MCOpcode << ' ' << Msg; + else + OS << " #ERROR " << Msg; +} + +static void CheckAndEmitMCOpcode(std::ostream &OS, const Opcode &X) { + if (X.has_opcode1()) + EmitMCOpcode(OS, X.opcode1()); + else if (X.has_opcode2()) + EmitMCOpcode(OS, X.opcode2()); + else if (X.has_opcode3()) + EmitMCOpcode(OS, X.opcode3()); + else if (X.has_opcode4()) + EmitMCOpcode(OS, X.opcode4()); + else if (X.has_opcode5()) + EmitMCOpcode(OS, X.opcode5()); + else if (X.has_opcode6()) + EmitMCOpcode(OS, X.opcode6()); + else if (X.has_opcode7()) + EmitMCOpcode(OS, X.opcode7()); + else if (X.has_opcode8()) + EmitMCOpcode(OS, X.opcode8()); + else if (X.has_opcode9()) + EmitMCOpcode(OS, X.opcode9()); + else if (X.has_opcode10()) + EmitMCOpcode(OS, X.opcode10()); + else if (X.has_opcode11()) + EmitMCOpcode(OS, X.opcode11()); + else if (X.has_opcode12()) + EmitMCOpcode(OS, X.opcode12()); + else if (X.has_opcode13()) + EmitMCOpcode(OS, X.opcode13()); + else if (X.has_opcode14()) + EmitMCOpcode(OS, X.opcode14()); + else if (X.has_opcode15()) + EmitMCOpcode(OS, X.opcode15()); + else if (X.has_opcode16()) + EmitMCOpcode(OS, X.opcode16()); + else if (X.has_opcode17()) + EmitMCOpcode(OS, X.opcode17()); + else if (X.has_opcode18()) + EmitMCOpcode(OS, X.opcode18()); + else if (X.has_opcode19()) + EmitMCOpcode(OS, X.opcode19()); + else if (X.has_opcode20()) + EmitMCOpcode(OS, X.opcode20()); + else if (X.has_opcode21()) + EmitMCOpcode(OS, X.opcode21()); + else if (X.has_opcode22()) + EmitMCOpcode(OS, X.opcode22()); + else if (X.has_opcode23()) + EmitMCOpcode(OS, X.opcode23()); + else if (X.has_opcode24()) + EmitMCOpcode(OS, X.opcode24()); + else if (X.has_opcode25()) + EmitMCOpcode(OS, X.opcode25()); + else if (X.has_opcode26()) + EmitMCOpcode(OS, X.opcode26()); + else if (X.has_opcode27()) + EmitMCOpcode(OS, X.opcode27()); + else if (X.has_opcode28()) + EmitMCOpcode(OS, X.opcode28()); + else if (X.has_opcode29()) + EmitMCOpcode(OS, X.opcode29()); + else if (X.has_opcode30()) + EmitMCOpcode(OS, X.opcode30()); + else if (X.has_opcode31()) + EmitMCOpcode(OS, X.opcode31()); + else if (X.has_opcode32()) + EmitMCOpcode(OS, X.opcode32()); + else if (X.has_opcode33()) + EmitMCOpcode(OS, X.opcode33()); + else if (X.has_opcode34()) + EmitMCOpcode(OS, X.opcode34()); + else if (X.has_opcode35()) + EmitMCOpcode(OS, X.opcode35()); + else if (X.has_opcode36()) + EmitMCOpcode(OS, X.opcode36()); + else if (X.has_opcode37()) + EmitMCOpcode(OS, X.opcode37()); + else if (X.has_opcode38()) + EmitMCOpcode(OS, X.opcode38()); + else if (X.has_opcode39()) + EmitMCOpcode(OS, X.opcode39()); + else if (X.has_opcode40()) + EmitMCOpcode(OS, X.opcode40()); + else if (X.has_opcode41()) + EmitMCOpcode(OS, X.opcode41()); + else if (X.has_opcode42()) + EmitMCOpcode(OS, X.opcode42()); + else if (X.has_opcode43()) + EmitMCOpcode(OS, X.opcode43()); + else if (X.has_opcode44()) + EmitMCOpcode(OS, X.opcode44()); + else if (X.has_opcode45()) + EmitMCOpcode(OS, X.opcode45()); + else if (X.has_opcode46()) + EmitMCOpcode(OS, X.opcode46()); + else if (X.has_opcode47()) + EmitMCOpcode(OS, X.opcode47()); + else if (X.has_opcode48()) + EmitMCOpcode(OS, X.opcode48()); + else if (X.has_opcode49()) + EmitMCOpcode(OS, X.opcode49()); + else if (X.has_opcode50()) + EmitMCOpcode(OS, X.opcode50()); + else if (X.has_opcode51()) + EmitMCOpcode(OS, X.opcode51()); + else if (X.has_opcode52()) + EmitMCOpcode(OS, X.opcode52()); + else if (X.has_opcode53()) + EmitMCOpcode(OS, X.opcode53()); + else if (X.has_opcode54()) + EmitMCOpcode(OS, X.opcode54()); + else if (X.has_opcode55()) + EmitMCOpcode(OS, X.opcode55()); + else if (X.has_opcode56()) + EmitMCOpcode(OS, X.opcode56()); + else if (X.has_opcode57()) + EmitMCOpcode(OS, X.opcode57()); + else if (X.has_opcode58()) + EmitMCOpcode(OS, X.opcode58()); + else if (X.has_opcode59()) + EmitMCOpcode(OS, X.opcode59()); + else if (X.has_opcode60()) + EmitMCOpcode(OS, X.opcode60()); + else if (X.has_opcode61()) + EmitMCOpcode(OS, X.opcode61()); + else if (X.has_opcode62()) + EmitMCOpcode(OS, X.opcode62()); + else if (X.has_opcode63()) + EmitMCOpcode(OS, X.opcode63()); + else if (X.has_opcode64()) + EmitMCOpcode(OS, X.opcode64()); + else if (X.has_opcode65()) + EmitMCOpcode(OS, X.opcode65()); + else if (X.has_opcode66()) + EmitMCOpcode(OS, X.opcode66()); + else if (X.has_opcode67()) + EmitMCOpcode(OS, X.opcode67()); + else if (X.has_opcode68()) + EmitMCOpcode(OS, X.opcode68()); + else { + auto Msg = "ADD"; + unsigned MCOpcode; + if (getMCOpcode(Msg, MCOpcode)) + OS << " #" << MCOpcode << ' ' << Msg; + else + OS << " #ERROR " << Msg; + } +} + +static void EmitMCOperand(std::ostream &OS, const Operand &X) { + OS << "\n# \n"; +} + + +static void EmitMC(std::ostream &OS, const AsmStmt &X) { + OS << "# "; +} + +#endif // EMIT_MC_INST + + + +// --------------------------------- +// Emit Assembly Instruction +// --------------------------------- +template +static void EmitAsm(std::ostream &OS, const T &X, + bool SkipReplace = false) { + std::string Msg; + getMessageName(X, Msg); std::transform(Msg.begin(), Msg.end(), Msg.begin(), ::tolower); if (!SkipReplace) std::replace(Msg.begin(), Msg.end(), '_', '.'); OS << Msg; } -namespace mc_proto_fuzzer { - template void Emit(std::ostream &OS, const T &X) { - const EnumDescriptor *ED = X.ValueRange_descriptor(); - EmitAsm(OS, ED, X.value()); + EmitAsm(OS, X); } std::ostream &operator<<(std::ostream &OS, const IORWString &X) { @@ -56,8 +251,7 @@ } std::ostream &operator<<(std::ostream &OS, const Modifier &X) { - const EnumDescriptor *ED = X.ValueRange_descriptor(); - EmitAsm(OS, ED, X.value(), true /* SkipReplace */); + EmitAsm(OS, X, true /* SkipReplace */); return OS; } @@ -282,19 +476,24 @@ std::ostream &operator<<(std::ostream &OS, const AsmStmt &X) { OS << "\t" << X.opcode() << "\t"; - int NumOperands = 0; + bool FirstOp = true; for (auto &Opnd : X.operands()) { - if (NumOperands != 0) - OS << ","; + if (FirstOp) + FirstOp = false; + else + OS << ','; OS << Opnd; - ++NumOperands; } return OS << "\n"; } std::ostream &operator<<(std::ostream &OS, const Assembly &X) { - for (auto &ST : X.stmts()) + for (auto &ST : X.stmts()) { OS << ST; +#ifdef EMIT_MC_INST + EmitMC(OS, ST); +#endif + } return OS; } Index: tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/riscv_support.h =================================================================== --- /dev/null +++ tools/llvm-mc-assemble-proto-fuzzer/proto-to-asm/riscv_support.h @@ -0,0 +1,82 @@ +//===- riscv_support.h ----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend emits llvm-exegesis information. +// +//===----------------------------------------------------------------------===// + + +// Defines symbolic names for RISC-V registers. +#define GET_REGINFO_ENUM +#include "RISCVGenRegisterInfo.inc" + +// Defines symbolic names for RISC-V instructions. +#define GET_INSTRINFO_ENUM +#include "RISCVGenInstrInfo.inc" + +using namespace llvm; +static std::map MCOpcodeMap { + {"ADD", RISCV::ADD}, + {"SUB", RISCV::SUB} +}; + +static std::map MCRegMap { + {"X0", RISCV::X0}, + {"X1", RISCV::X1}, + {"X2", RISCV::X2}, + {"X3", RISCV::X3}, + {"X4", RISCV::X4}, + {"X5", RISCV::X5}, + {"X6", RISCV::X6}, + {"X7", RISCV::X7}, + {"X8", RISCV::X8}, + {"X9", RISCV::X9}, + {"X10", RISCV::X10}, + {"X11", RISCV::X11}, + {"X12", RISCV::X12}, + {"X13", RISCV::X13}, + {"X14", RISCV::X14}, + {"X15", RISCV::X15}, + {"X16", RISCV::X16}, + {"X17", RISCV::X17}, + {"X18", RISCV::X18}, + {"X19", RISCV::X19}, + {"X20", RISCV::X20}, + {"X21", RISCV::X21}, + {"X22", RISCV::X22}, + {"X23", RISCV::X23}, + {"X24", RISCV::X24}, + {"X25", RISCV::X25}, + {"X26", RISCV::X26}, + {"X27", RISCV::X27}, + {"X28", RISCV::X28}, + {"X29", RISCV::X29}, + {"X30", RISCV::X30}, + {"X31", RISCV::X31} +}; + +namespace { +static bool getMCOpcode(const std::string &Opcode, unsigned &MCOpcode) { + auto I = MCOpcodeMap.find(Opcode); + if (I == MCOpcodeMap.end()) + return false; + MCOpcode = I->second; + return true; +} + +static bool getMCReg(const std::string &Opcode, unsigned &MCReg) { + auto I = MCRegMap.find(Opcode); + if (I == MCRegMap.end()) + return false; + MCReg = I->second; + return true; +} + +} // end anonymous namespace. +