From a16c51cee9225a354c999dd1076d5dba2aa79807 Mon Sep 17 00:00:00 2001 From: rdivacky Date: Fri, 1 Jan 2010 10:31:22 +0000 Subject: Update LLVM to 92395. --- tools/llvm-mc/AsmParser.cpp | 5 +- tools/llvm-mc/CMakeLists.txt | 1 + tools/llvm-mc/Disassembler.cpp | 165 ++++++++++++++++++++ tools/llvm-mc/Disassembler.h | 34 +++++ tools/llvm-mc/HexDisassembler.cpp | 169 +++++++++++++++++++++ tools/llvm-mc/HexDisassembler.h | 34 +++++ tools/llvm-mc/llvm-mc.cpp | 37 ++++- tools/llvmc/doc/LLVMC-Reference.rst | 46 +++--- tools/llvmc/doc/Makefile | 6 + .../example/mcc16/plugins/PIC16Base/PIC16Base.td | 99 ++++++------ tools/llvmc/plugins/Base/Base.td.in | 11 +- tools/lto/LTOCodeGenerator.h | 5 +- tools/lto/LTOModule.h | 3 +- 13 files changed, 539 insertions(+), 76 deletions(-) create mode 100644 tools/llvm-mc/Disassembler.cpp create mode 100644 tools/llvm-mc/Disassembler.h create mode 100644 tools/llvm-mc/HexDisassembler.cpp create mode 100644 tools/llvm-mc/HexDisassembler.h (limited to 'tools') diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 436f17d..1204a00 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -22,6 +22,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetAsmParser.h" @@ -963,7 +964,7 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) { if (Lexer.isNot(AsmToken::EndOfStatement)) { for (;;) { const MCExpr *Value; - SMLoc StartLoc = Lexer.getLoc(); + SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc(); if (ParseExpression(Value)) return true; @@ -1631,7 +1632,7 @@ bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { if (Lexer.isNot(AsmToken::String)) return TokError("unexpected token in '.file' directive"); - StringRef FileName = Lexer.getTok().getString(); + StringRef ATTRIBUTE_UNUSED FileName = Lexer.getTok().getString(); Lexer.Lex(); if (Lexer.isNot(AsmToken::EndOfStatement)) diff --git a/tools/llvm-mc/CMakeLists.txt b/tools/llvm-mc/CMakeLists.txt index ce9d63b..46c5c6b 100644 --- a/tools/llvm-mc/CMakeLists.txt +++ b/tools/llvm-mc/CMakeLists.txt @@ -4,4 +4,5 @@ add_llvm_tool(llvm-mc llvm-mc.cpp AsmLexer.cpp AsmParser.cpp + Disassembler.cpp ) diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp new file mode 100644 index 0000000..5fde712 --- /dev/null +++ b/tools/llvm-mc/Disassembler.cpp @@ -0,0 +1,165 @@ +//===- Disassembler.cpp - Disassembler for hex strings --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class implements the disassembler of strings of bytes written in +// hexadecimal, from standard input or from a file. +// +//===----------------------------------------------------------------------===// + +#include "Disassembler.h" + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/MemoryObject.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SourceMgr.h" +using namespace llvm; + +typedef std::vector > ByteArrayTy; + +namespace { +class VectorMemoryObject : public MemoryObject { +private: + const ByteArrayTy &Bytes; +public: + VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} + + uint64_t getBase() const { return 0; } + uint64_t getExtent() const { return Bytes.size(); } + + int readByte(uint64_t Addr, uint8_t *Byte) const { + if (Addr > getExtent()) + return -1; + *Byte = Bytes[Addr].first; + return 0; + } +}; +} + +static bool PrintInst(const llvm::MCDisassembler &DisAsm, + llvm::MCInstPrinter &Printer, const ByteArrayTy &Bytes, + SourceMgr &SM) { + // Wrap the vector in a MemoryObject. + VectorMemoryObject memoryObject(Bytes); + + // Disassemble it to a string and get the size of the instruction. + MCInst Inst; + uint64_t Size; + + if (!DisAsm.getInstruction(Inst, Size, memoryObject, 0, + /*REMOVE*/ nulls())) { + SM.PrintMessage(SMLoc::getFromPointer(Bytes[0].second), + "invalid instruction encoding", "error"); + return true; + } + + Printer.printInst(&Inst); + outs() << "\n"; + + // If the disassembled instruction was smaller than the number of bytes we + // read, reject the excess bytes. + if (Bytes.size() != Size) { + SM.PrintMessage(SMLoc::getFromPointer(Bytes[Size].second), + "excess data detected in input", "error"); + return true; + } + + return false; +} + +int Disassembler::disassemble(const Target &T, const std::string &Triple, + MemoryBuffer &Buffer) { + // Set up disassembler. + llvm::OwningPtr AsmInfo(T.createAsmInfo(Triple)); + + if (!AsmInfo) { + errs() << "error: no assembly info for target " << Triple << "\n"; + return -1; + } + + llvm::OwningPtr DisAsm(T.createMCDisassembler()); + if (!DisAsm) { + errs() << "error: no disassembler for target " << Triple << "\n"; + return -1; + } + + llvm::MCInstPrinter *InstPrinter = T.createMCInstPrinter(0, *AsmInfo, outs()); + + if (!InstPrinter) { + errs() << "error: no instruction printer for target " << Triple << '\n'; + return -1; + } + + bool ErrorOccurred = false; + + SourceMgr SM; + SM.AddNewSourceBuffer(&Buffer, SMLoc()); + + // Convert the input to a vector for disassembly. + ByteArrayTy ByteArray; + + StringRef Str = Buffer.getBuffer(); + while (!Str.empty()) { + // Strip horizontal whitespace. + if (size_t Pos = Str.find_first_not_of(" \t\r")) { + Str = Str.substr(Pos); + continue; + } + + // If this is the end of a line or start of a comment, process the + // instruction we have so far. + if (Str[0] == '\n' || Str[0] == '#') { + // If we have bytes to process, do so. + if (!ByteArray.empty()) { + ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); + ByteArray.clear(); + } + + // Strip to the end of line if we already processed any bytes on this + // line. This strips the comment and/or the \n. + if (Str[0] == '\n') + Str = Str.substr(1); + else { + Str = Str.substr(Str.find_first_of('\n')); + if (!Str.empty()) + Str = Str.substr(1); + } + continue; + } + + // Get the current token. + size_t Next = Str.find_first_of(" \t\n\r#"); + StringRef Value = Str.substr(0, Next); + + // Convert to a byte and add to the byte vector. + unsigned ByteVal; + if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) { + // If we have an error, print it and skip to the end of line. + SM.PrintMessage(SMLoc::getFromPointer(Value.data()), + "invalid input token", "error"); + ErrorOccurred = true; + Str = Str.substr(Str.find('\n')); + ByteArray.clear(); + continue; + } + + ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); + Str = Str.substr(Next); + } + + if (!ByteArray.empty()) + ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); + + return ErrorOccurred; +} diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h new file mode 100644 index 0000000..78c2f85 --- /dev/null +++ b/tools/llvm-mc/Disassembler.h @@ -0,0 +1,34 @@ +//===- Disassembler.h - Text File Disassembler ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class implements the disassembler of strings of bytes written in +// hexadecimal, from standard input or from a file. +// +//===----------------------------------------------------------------------===// + +#ifndef DISASSEMBLER_H +#define DISASSEMBLER_H + +#include + +namespace llvm { + +class Target; +class MemoryBuffer; + +class Disassembler { +public: + static int disassemble(const Target &target, + const std::string &tripleString, + MemoryBuffer &buffer); +}; + +} // namespace llvm + +#endif diff --git a/tools/llvm-mc/HexDisassembler.cpp b/tools/llvm-mc/HexDisassembler.cpp new file mode 100644 index 0000000..7435c10 --- /dev/null +++ b/tools/llvm-mc/HexDisassembler.cpp @@ -0,0 +1,169 @@ +//===- HexDisassembler.cpp - Disassembler for hex strings -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class implements the disassembler of strings of bytes written in +// hexadecimal, from standard input or from a file. +// +//===----------------------------------------------------------------------===// + +#include "HexDisassembler.h" + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/MemoryObject.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SourceMgr.h" +using namespace llvm; + +typedef std::vector > ByteArrayTy; + +namespace { +class VectorMemoryObject : public MemoryObject { +private: + const ByteArrayTy &Bytes; +public: + VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} + + uint64_t getBase() const { return 0; } + uint64_t getExtent() const { return Bytes.size(); } + + int readByte(uint64_t Addr, uint8_t *Byte) const { + if (Addr > getExtent()) + return -1; + *Byte = Bytes[Addr].first; + return 0; + } +}; +} + +static bool PrintInst(const llvm::MCDisassembler &DisAsm, + llvm::MCInstPrinter &Printer, const ByteArrayTy &Bytes, + SourceMgr &SM) { + // Wrap the vector in a MemoryObject. + VectorMemoryObject memoryObject(Bytes); + + // Disassemble it to a string and get the size of the instruction. + MCInst Inst; + uint64_t Size; + + std::string verboseOStr; + llvm::raw_string_ostream verboseOS(verboseOStr); + + if (!DisAsm.getInstruction(Inst, Size, memoryObject, 0, verboseOS)) { + SM.PrintMessage(SMLoc::getFromPointer(Bytes[0].second), + "invalid instruction encoding", "error"); + errs() << "Diagnostic log:" << '\n'; + errs() << verboseOS.str() << '\n'; + return true; + } + + Printer.printInst(&Inst); + outs() << "\n"; + + // If the disassembled instruction was smaller than the number of bytes we + // read, reject the excess bytes. + if (Bytes.size() != Size) { + SM.PrintMessage(SMLoc::getFromPointer(Bytes[Size].second), + "excess data detected in input", "error"); + return true; + } + + return false; +} + +int HexDisassembler::disassemble(const Target &T, const std::string &Triple, + MemoryBuffer &Buffer) { + // Set up disassembler. + llvm::OwningPtr AsmInfo(T.createAsmInfo(Triple)); + + if (!AsmInfo) { + errs() << "error: no assembly info for target " << Triple << "\n"; + return -1; + } + + llvm::OwningPtr DisAsm(T.createMCDisassembler()); + if (!DisAsm) { + errs() << "error: no disassembler for target " << Triple << "\n"; + return -1; + } + + llvm::MCInstPrinter *InstPrinter = T.createMCInstPrinter(0, *AsmInfo, outs()); + + if (!InstPrinter) { + errs() << "error: no instruction printer for target " << Triple << '\n'; + return -1; + } + + bool ErrorOccurred = false; + + SourceMgr SM; + SM.AddNewSourceBuffer(&Buffer, SMLoc()); + + // Convert the input to a vector for disassembly. + ByteArrayTy ByteArray; + + StringRef Str = Buffer.getBuffer(); + while (!Str.empty()) { + // Strip horizontal whitespace. + if (size_t Pos = Str.find_first_not_of(" \t\r")) { + Str = Str.substr(Pos); + continue; + } + + // If this is the end of a line or start of a comment, process the + // instruction we have so far. + if (Str[0] == '\n' || Str[0] == '#') { + // If we have bytes to process, do so. + if (!ByteArray.empty()) { + ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); + ByteArray.clear(); + } + + // Strip to the end of line if we already processed any bytes on this + // line. This strips the comment and/or the \n. + if (Str[0] == '\n') + Str = Str.substr(1); + else { + Str = Str.substr(Str.find_first_of('\n')); + if (!Str.empty()) + Str = Str.substr(1); + } + continue; + } + + // Get the current token. + size_t Next = Str.find_first_of(" \t\n\r#"); + StringRef Value = Str.substr(0, Next); + + // Convert to a byte and add to the byte vector. + unsigned ByteVal; + if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) { + // If we have an error, print it and skip to the end of line. + SM.PrintMessage(SMLoc::getFromPointer(Value.data()), + "invalid input token", "error"); + ErrorOccurred = true; + Str = Str.substr(Str.find('\n')); + ByteArray.clear(); + continue; + } + + ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); + Str = Str.substr(Next); + } + + if (!ByteArray.empty()) + ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); + + return ErrorOccurred; +} diff --git a/tools/llvm-mc/HexDisassembler.h b/tools/llvm-mc/HexDisassembler.h new file mode 100644 index 0000000..d197aea --- /dev/null +++ b/tools/llvm-mc/HexDisassembler.h @@ -0,0 +1,34 @@ +//===- HexDisassembler.h - Disassembler for hex strings -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class implements the disassembler of strings of bytes written in +// hexadecimal, from standard input or from a file. +// +//===----------------------------------------------------------------------===// + +#ifndef HEXDISASSEMBLER_H +#define HEXDISASSEMBLER_H + +#include + +namespace llvm { + +class Target; +class MemoryBuffer; + +class HexDisassembler { +public: + static int disassemble(const Target &target, + const std::string &tripleString, + MemoryBuffer &buffer); +}; + +} // namespace llvm + +#endif diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 76552b8..30cdfba 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -32,6 +32,7 @@ #include "llvm/Target/TargetMachine.h" // FIXME. #include "llvm/Target/TargetSelect.h" #include "AsmParser.h" +#include "Disassembler.h" using namespace llvm; static cl::opt @@ -76,7 +77,8 @@ TripleName("triple", cl::desc("Target triple to assemble for, " enum ActionType { AC_AsLex, - AC_Assemble + AC_Assemble, + AC_Disassemble }; static cl::opt @@ -86,6 +88,8 @@ Action(cl::desc("Action to perform:"), "Lex tokens from a .s file"), clEnumValN(AC_Assemble, "assemble", "Assemble a .s file (default)"), + clEnumValN(AC_Disassemble, "disassemble", + "Disassemble strings of hex bytes"), clEnumValEnd)); static const Target *GetTarget(const char *ProgName) { @@ -281,7 +285,33 @@ static int AssembleInput(const char *ProgName) { delete Out; return Res; -} +} + +static int DisassembleInput(const char *ProgName) { + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); + if (TheTarget == 0) { + errs() << ProgName << ": error: unable to get target for '" << TripleName + << "', see --version and --triple.\n"; + return 0; + } + + std::string ErrorMessage; + + MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, + &ErrorMessage); + + if (Buffer == 0) { + errs() << ProgName << ": "; + if (ErrorMessage.size()) + errs() << ErrorMessage << "\n"; + else + errs() << "input file didn't read correctly.\n"; + return 1; + } + + return Disassembler::disassemble(*TheTarget, TripleName, *Buffer); +} int main(int argc, char **argv) { @@ -296,6 +326,7 @@ int main(int argc, char **argv) { llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); @@ -305,6 +336,8 @@ int main(int argc, char **argv) { return AsLexInput(argv[0]); case AC_Assemble: return AssembleInput(argv[0]); + case AC_Disassemble: + return DisassembleInput(argv[0]); } return 0; diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst index 4d80a2a..dfe3898 100644 --- a/tools/llvmc/doc/LLVMC-Reference.rst +++ b/tools/llvmc/doc/LLVMC-Reference.rst @@ -656,10 +656,10 @@ For example, without those definitions the following command wouldn't work:: $ llvmc hello.cpp llvmc: Unknown suffix: cpp -The language map entries should be added only for tools that are -linked with the root node. Since tools are not allowed to have -multiple output languages, for nodes "inside" the graph the input and -output languages should match. This is enforced at compile-time. +The language map entries are needed only for the tools that are linked from the +root node. Since a tool can't have multiple output languages, for inner nodes of +the graph the input and output languages should match. This is enforced at +compile-time. Option preprocessor =================== @@ -672,24 +672,34 @@ the driver with both of these options enabled. The ``OptionPreprocessor`` feature is reserved specially for these occasions. Example (adapted from the built-in Base plugin):: - def Preprocess : OptionPreprocessor< - (case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), - [(unset_option ["O0", "O1", "O2"]), - (warning "Multiple -O options specified, defaulted to -O3.")], - (and (switch_on "O2"), (any_switch_on ["O0", "O1"])), - (unset_option ["O0", "O1"]), - (and (switch_on "O1"), (switch_on "O0")), - (unset_option "O0")) - >; -Here, ``OptionPreprocessor`` is used to unset all spurious optimization options -(so that they are not forwarded to the compiler). + def Preprocess : OptionPreprocessor< + (case (not (any_switch_on ["O0", "O1", "O2", "O3"])), + (set_option "O2"), + (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), + (unset_option ["O0", "O1", "O2"]), + (and (switch_on "O2"), (any_switch_on ["O0", "O1"])), + (unset_option ["O0", "O1"]), + (and (switch_on "O1"), (switch_on "O0")), + (unset_option "O0")) + >; + +Here, ``OptionPreprocessor`` is used to unset all spurious ``-O`` options so +that they are not forwarded to the compiler. If no optimization options are +specified, ``-O2`` is enabled. ``OptionPreprocessor`` is basically a single big ``case`` expression, which is evaluated only once right after the plugin is loaded. The only allowed actions -in ``OptionPreprocessor`` are ``error``, ``warning`` and a special action -``unset_option``, which, as the name suggests, unsets a given option. For -convenience, ``unset_option`` also works on lists. +in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions: +``unset_option`` and ``set_option``. As their names suggest, they can be used to +set or unset a given option. To set an option with ``set_option``, use the +two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be +either a string, a string list, or a boolean constant. + +For convenience, ``set_option`` and ``unset_option`` also work on lists. That +is, instead of ``[(unset_option "A"), (unset_option "B")]`` you can use +``(unset_option ["A", "B"])``. Obviously, ``(set_option ["A", "B"])`` is valid +only if both ``A`` and ``B`` are switches. More advanced topics diff --git a/tools/llvmc/doc/Makefile b/tools/llvmc/doc/Makefile index 65e6b9b..ef98767 100644 --- a/tools/llvmc/doc/Makefile +++ b/tools/llvmc/doc/Makefile @@ -8,7 +8,13 @@ ##===----------------------------------------------------------------------===## LEVEL=../../.. + +ifneq (,$(strip $(wildcard $(LEVEL)/Makefile.config))) include $(LEVEL)/Makefile.config +else +CP=cp +RM=rm +endif DOC_DIR=../../../docs RST2HTML=rst2html --stylesheet=llvm.css --link-stylesheet diff --git a/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td index 5e6f6cb..717e95e 100644 --- a/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td +++ b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td @@ -19,6 +19,8 @@ def OptionList : OptionList<[ (help "Stop after b-code generation, do not compile")), (switch_option "c", (help "Stop after assemble, do not link")), + (prefix_option "p", + (help "Specify part name")), (prefix_list_option "I", (help "Add a directory to include path")), (prefix_list_option "L", @@ -33,22 +35,27 @@ def OptionList : OptionList<[ (help "Generate linker map file with the given name")), (prefix_list_option "D", (help "Define a macro")), + (switch_option "X", + (help "Do not invoke mp2hex to create an output hex file.")), (switch_option "O0", (help "Do not optimize")), -// (switch_option "O1", -// (help "Optimization level 1")), -// (switch_option "O2", -// (help "Optimization level 2. (Default)")), -// (parameter_option "pre-RA-sched", -// (help "Example of an option that is passed to llc")), - (prefix_list_option "Wa,", (comma_separated), - (help "Pass options to native assembler")), - (prefix_list_option "Wl,", (comma_separated), - (help "Pass options to native linker")) -// (prefix_list_option "Wllc,", -// (help "Pass options to llc")), -// (prefix_list_option "Wo,", -// (help "Pass options to llvm-ld")) + (switch_option "O1", + (help "Optimization Level 1.")), + (switch_option "O2", + (help "Optimization Level 2.")), + (switch_option "O3", + (help "Optimization Level 3.")), + (switch_option "Od", + (help "Perform Debug-safe Optimizations only.")), + (switch_option "r", + (help "Use resource file for part info"), + (really_hidden)), + (parameter_option "regalloc", + (help "Register allocator to use.(possible values: simple, linearscan, pbqp, local. default = pbqp)")), + (prefix_list_option "Wa,", + (help "Pass options to assembler (Run 'gpasm -help' for assembler options)")), + (prefix_list_option "Wl,", + (help "Pass options to linker (Run 'mplink -help' for linker options)")) ]>; // Tools @@ -58,34 +65,27 @@ class clang_based : Tool< (output_suffix "bc"), (cmd_line (case (switch_on "E"), - (case + (case (not_empty "o"), !strconcat(cmd, " -E $INFILE -o $OUTFILE"), (default), !strconcat(cmd, " -E $INFILE")), (default), !strconcat(cmd, " $INFILE -o $OUTFILE"))), - (actions (case + (actions (case (and (multiple_input_files), (or (switch_on "S"), (switch_on "c"))), (error "cannot specify -o with -c or -S with multiple files"), (switch_on "E"), [(stop_compilation), (output_suffix ext_E)], (switch_on "bc"),[(stop_compilation), (output_suffix "bc")], (switch_on "g"), (append_cmd "-g"), + (switch_on "O1"), (append_cmd ""), + (switch_on "O2"), (append_cmd ""), + (switch_on "O3"), (append_cmd ""), + (switch_on "Od"), (append_cmd ""), (not_empty "D"), (forward "D"), - (not_empty "I"), (forward "I"))), - (sink) + (not_empty "I"), (forward "I"), + (switch_on "O0"), (append_cmd "-O0"), + (default), (append_cmd "-O1"))) ]>; -def clang_cc : clang_based<"c", "$CALL(GetBinDir)clang-cc -I $CALL(GetStdHeadersDir) -triple=pic16- -emit-llvm-bc ", "i">; - -//def clang_cc : Tool<[ -// (in_language "c"), -// (out_language "llvm-bitcode"), -// (output_suffix "bc"), -// (cmd_line "$CALL(GetBinDir)clang-cc -I $CALL(GetStdHeadersDir) -triple=pic16- -emit-llvm-bc "), -// (cmd_line kkkkk -// (actions (case -// (switch_on "g"), (append_cmd "g"), -// (not_empty "I"), (forward "I"))), -// (sink) -//]>; +def clang_cc : clang_based<"c", "$CALL(GetBinDir)clang -cc1 -I $CALL(GetStdHeadersDir) -triple=pic16- -emit-llvm-bc ", "i">; // pre-link-and-lto step. @@ -93,9 +93,14 @@ def llvm_ld : Tool<[ (in_language "llvm-bitcode"), (out_language "llvm-bitcode"), (output_suffix "bc"), - (cmd_line "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -disable-gvn -instcombine -disable-inlining $INFILE -b $OUTFILE -l std"), + (cmd_line "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -instcombine -disable-licm-promotion $INFILE -b $OUTFILE -l std"), (actions (case - (switch_on "O0"), (append_cmd "-disable-opt"))), + (switch_on "O0"), (append_cmd "-disable-opt"), + (switch_on "O1"), (append_cmd "-disable-opt"), + (switch_on "O2"), (append_cmd ""), +// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added. + (switch_on "O3"), (append_cmd ""), + (default), (append_cmd "-disable-inlining"))), (join) ]>; @@ -104,7 +109,7 @@ def llvm_ld_optimizer : Tool<[ (in_language "llvm-bitcode"), (out_language "llvm-bitcode"), (output_suffix "bc"), - (cmd_line "$CALL(GetBinDir)llvm-ld -disable-gvn -instcombine -disable-inlining $INFILE -b $OUTFILE"), + (cmd_line "$CALL(GetBinDir)llvm-ld -instcombine -disable-inlining $INFILE -b $OUTFILE"), (actions (case (switch_on "O0"), (append_cmd "-disable-opt"))) ]>; @@ -114,7 +119,7 @@ def pic16passes : Tool<[ (in_language "llvm-bitcode"), (out_language "llvm-bitcode"), (output_suffix "obc"), - (cmd_line "$CALL(GetBinDir)opt -pic16cg -pic16overlay $INFILE -f -o $OUTFILE"), + (cmd_line "$CALL(GetBinDir)opt -pic16overlay $INFILE -f -o $OUTFILE"), (actions (case (switch_on "O0"), (append_cmd "-disable-opt"))) ]>; @@ -123,21 +128,24 @@ def llc : Tool<[ (in_language "llvm-bitcode"), (out_language "assembler"), (output_suffix "s"), - (cmd_line "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -regalloc=pbqp -f $INFILE -o $OUTFILE"), + (cmd_line "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -f $INFILE -o $OUTFILE"), (actions (case - (switch_on "S"), (stop_compilation))) -// (not_empty "Wllc,"), (unpack_values "Wllc,"), -// (not_empty "pre-RA-sched"), (forward "pre-RA-sched"))) + (switch_on "S"), (stop_compilation), + (not_empty "regalloc"), (forward "regalloc"), + (empty "regalloc"), (append_cmd "-regalloc=pbqp"))) ]>; def gpasm : Tool<[ (in_language "assembler"), (out_language "object-code"), (output_suffix "o"), - (cmd_line "$CALL(GetBinDir)gpasm -r decimal -p p16F1937 -I $CALL(GetStdAsmHeadersDir) -C -c -q $INFILE -o $OUTFILE"), + (cmd_line "$CALL(GetBinDir)gpasm -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2 $INFILE -o $OUTFILE"), (actions (case (switch_on "c"), (stop_compilation), (switch_on "g"), (append_cmd "-g"), + (switch_on "r"), (append_cmd "-z"), + (not_empty "p"), (forward "p"), + (empty "p"), (append_cmd "-p 16f1xxx"), (not_empty "Wa,"), (forward_value "Wa,"))) ]>; @@ -145,13 +153,16 @@ def mplink : Tool<[ (in_language "object-code"), (out_language "executable"), (output_suffix "cof"), - (cmd_line "$CALL(GetBinDir)mplink.exe -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) -p 16f1937 intrinsics.lib devices.lib $INFILE -o $OUTFILE"), + (cmd_line "$CALL(GetBinDir)mplink -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib $INFILE -o $OUTFILE"), (actions (case (not_empty "Wl,"), (forward_value "Wl,"), + (switch_on "r"), (append_cmd "-e"), + (switch_on "X"), (append_cmd "-x"), (not_empty "L"), (forward_as "L", "-l"), (not_empty "K"), (forward_as "K", "-k"), (not_empty "m"), (forward "m"), -// (not_empty "l"), [(unpack_values "l"),(append_cmd ".lib")])), + (not_empty "p"), [(forward "p"), (append_cmd "-c")], + (empty "p"), (append_cmd "-p 16f1xxx -c"), (not_empty "k"), (forward_value "k"), (not_empty "l"), (forward_value "l"))), (join) @@ -175,13 +186,13 @@ def LanguageMap : LanguageMap<[ def CompilationGraph : CompilationGraph<[ Edge<"root", "clang_cc">, Edge<"root", "llvm_ld">, - OptionalEdge<"root", "llvm_ld_optimizer", (case + OptionalEdge<"root", "llvm_ld_optimizer", (case (switch_on "S"), (inc_weight), (switch_on "c"), (inc_weight))>, Edge<"root", "gpasm">, Edge<"root", "mplink">, Edge<"clang_cc", "llvm_ld">, - OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case + OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case (switch_on "S"), (inc_weight), (switch_on "c"), (inc_weight))>, Edge<"llvm_ld", "pic16passes">, diff --git a/tools/llvmc/plugins/Base/Base.td.in b/tools/llvmc/plugins/Base/Base.td.in index 8f928cc..c7ba3be 100644 --- a/tools/llvmc/plugins/Base/Base.td.in +++ b/tools/llvmc/plugins/Base/Base.td.in @@ -91,15 +91,16 @@ def OptList : OptionList<[ // Option preprocessor. def Preprocess : OptionPreprocessor< -(case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), +(case (not (any_switch_on ["O0", "O1", "O2", "O3"])), + (set_option "O2"), + (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), (unset_option ["O0", "O1", "O2"]), (and (switch_on "O2"), (any_switch_on ["O0", "O1"])), (unset_option ["O0", "O1"]), - (and (switch_on "O1"), (switch_on "O0")), + (switch_on ["O1", "O0"]), (unset_option "O0")) >; - // Tools class llvm_gcc_based : Tool< @@ -123,9 +124,9 @@ class llvm_gcc_based : Tool< (and (multiple_input_files), (or (switch_on "S"), (switch_on "c"))), (error "cannot specify -o with -c or -S with multiple files"), (switch_on "E"), [(stop_compilation), (output_suffix E_ext)], - (and (switch_on "emit-llvm"), (switch_on "S")), + (switch_on ["emit-llvm", "S"]), [(output_suffix "ll"), (stop_compilation)], - (and (switch_on "emit-llvm"), (switch_on "c")), (stop_compilation), + (switch_on ["emit-llvm", "c"]), (stop_compilation), (switch_on "fsyntax-only"), (stop_compilation), (not_empty "include"), (forward "include"), (not_empty "save-temps"), (append_cmd "-save-temps"), diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 0ebec2c..cac3b8c 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -27,14 +27,13 @@ // C++ class which implements the opaque lto_code_gen_t // -class LTOCodeGenerator { -public: +struct LTOCodeGenerator { static const char* getVersionString(); LTOCodeGenerator(); ~LTOCodeGenerator(); - bool addModule(class LTOModule*, std::string& errMsg); + bool addModule(struct LTOModule*, std::string& errMsg); bool setDebugInfo(lto_debug_model, std::string& errMsg); bool setCodePICModel(lto_codegen_model, std::string& errMsg); void setAssemblerPath(const char* path); diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h index 4019e01..7f475d4 100644 --- a/tools/lto/LTOModule.h +++ b/tools/lto/LTOModule.h @@ -38,8 +38,7 @@ namespace llvm { // // C++ class which implements the opaque lto_module_t // -class LTOModule { -public: +struct LTOModule { static bool isBitcodeFile(const void* mem, size_t length); static bool isBitcodeFile(const char* path); -- cgit v1.1