summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-01-01 10:31:22 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-01-01 10:31:22 +0000
commita16c51cee9225a354c999dd1076d5dba2aa79807 (patch)
treedba00119388b84f9f44e6ec5e9129f807fd79ca3 /tools
parent40a6fcdb85efd93fe0e36c9552cfb0b18b5eacd6 (diff)
downloadFreeBSD-src-a16c51cee9225a354c999dd1076d5dba2aa79807.zip
FreeBSD-src-a16c51cee9225a354c999dd1076d5dba2aa79807.tar.gz
Update LLVM to 92395.
Diffstat (limited to 'tools')
-rw-r--r--tools/llvm-mc/AsmParser.cpp5
-rw-r--r--tools/llvm-mc/CMakeLists.txt1
-rw-r--r--tools/llvm-mc/Disassembler.cpp165
-rw-r--r--tools/llvm-mc/Disassembler.h34
-rw-r--r--tools/llvm-mc/HexDisassembler.cpp169
-rw-r--r--tools/llvm-mc/HexDisassembler.h34
-rw-r--r--tools/llvm-mc/llvm-mc.cpp37
-rw-r--r--tools/llvmc/doc/LLVMC-Reference.rst46
-rw-r--r--tools/llvmc/doc/Makefile6
-rw-r--r--tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td99
-rw-r--r--tools/llvmc/plugins/Base/Base.td.in11
-rw-r--r--tools/lto/LTOCodeGenerator.h5
-rw-r--r--tools/lto/LTOModule.h3
13 files changed, 539 insertions, 76 deletions
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<std::pair<unsigned char, const char*> > 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<const llvm::MCAsmInfo> AsmInfo(T.createAsmInfo(Triple));
+
+ if (!AsmInfo) {
+ errs() << "error: no assembly info for target " << Triple << "\n";
+ return -1;
+ }
+
+ llvm::OwningPtr<const llvm::MCDisassembler> 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 <string>
+
+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<std::pair<unsigned char, const char*> > 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<const llvm::MCAsmInfo> AsmInfo(T.createAsmInfo(Triple));
+
+ if (!AsmInfo) {
+ errs() << "error: no assembly info for target " << Triple << "\n";
+ return -1;
+ }
+
+ llvm::OwningPtr<const llvm::MCDisassembler> 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 <string>
+
+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<std::string>
@@ -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<ActionType>
@@ -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<string language, string cmd, string ext_E> : 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 <string cmd_prefix, string in_lang, string E_ext> : Tool<
@@ -123,9 +124,9 @@ class llvm_gcc_based <string cmd_prefix, string in_lang, string E_ext> : 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);
OpenPOWER on IntegriCloud