aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-mc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-mc')
-rw-r--r--tools/llvm-mc/Disassembler.cpp46
-rw-r--r--tools/llvm-mc/Disassembler.h2
-rw-r--r--tools/llvm-mc/Makefile17
-rw-r--r--tools/llvm-mc/llvm-mc.cpp170
4 files changed, 140 insertions, 95 deletions
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index c389f6a953..e0064888de 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -21,14 +21,15 @@
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/Target/TargetRegistry.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy;
@@ -65,15 +66,28 @@ static bool PrintInsts(const MCDisassembler &DisAsm,
for (Index = 0; Index < Bytes.size(); Index += Size) {
MCInst Inst;
- if (DisAsm.getInstruction(Inst, Size, memoryObject, Index,
- /*REMOVE*/ nulls())) {
- Printer.printInst(&Inst, Out);
- Out << "\n";
- } else {
+ MCDisassembler::DecodeStatus S;
+ S = DisAsm.getInstruction(Inst, Size, memoryObject, Index,
+ /*REMOVE*/ nulls(), nulls());
+ switch (S) {
+ case MCDisassembler::Fail:
SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
- "invalid instruction encoding", "warning");
+ SourceMgr::DK_Warning,
+ "invalid instruction encoding");
if (Size == 0)
Size = 1; // skip illegible bytes
+ break;
+
+ case MCDisassembler::SoftFail:
+ SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
+ SourceMgr::DK_Warning,
+ "potentially undefined instruction encoding");
+ // Fall through
+
+ case MCDisassembler::Success:
+ Printer.printInst(&Inst, Out, "");
+ Out << "\n";
+ break;
}
}
@@ -113,8 +127,8 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray,
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");
+ SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error,
+ "invalid input token");
Str = Str.substr(Str.find('\n'));
ByteArray.clear();
continue;
@@ -129,6 +143,8 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray,
int Disassembler::disassemble(const Target &T,
const std::string &Triple,
+ const std::string &Cpu,
+ const std::string &FeaturesStr,
MemoryBuffer &Buffer,
raw_ostream &Out) {
// Set up disassembler.
@@ -139,7 +155,13 @@ int Disassembler::disassemble(const Target &T,
return -1;
}
- OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler());
+ OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu, FeaturesStr));
+ if (!STI) {
+ errs() << "error: no subtarget info for target " << Triple << "\n";
+ return -1;
+ }
+
+ OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI));
if (!DisAsm) {
errs() << "error: no disassembler for target " << Triple << "\n";
return -1;
@@ -147,7 +169,7 @@ int Disassembler::disassemble(const Target &T,
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant,
- *AsmInfo));
+ *AsmInfo, *STI));
if (!IP) {
errs() << "error: no instruction printer for target " << Triple << '\n';
return -1;
diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h
index 433e71bf27..e8cd92db03 100644
--- a/tools/llvm-mc/Disassembler.h
+++ b/tools/llvm-mc/Disassembler.h
@@ -27,6 +27,8 @@ class Disassembler {
public:
static int disassemble(const Target &target,
const std::string &tripleString,
+ const std::string &Cpu,
+ const std::string &FeaturesStr,
MemoryBuffer &buffer,
raw_ostream &Out);
diff --git a/tools/llvm-mc/Makefile b/tools/llvm-mc/Makefile
index 934a6e4dd0..b147fadb57 100644
--- a/tools/llvm-mc/Makefile
+++ b/tools/llvm-mc/Makefile
@@ -7,18 +7,11 @@
#
##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = llvm-mc
+LEVEL := ../..
+TOOLNAME := llvm-mc
+LINK_COMPONENTS := all-targets MCDisassembler MCParser MC support
# This tool has no plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-# Include this here so we can get the configuration of the targets
-# that have been configured for construction. We have to do this
-# early so we can set up LINK_COMPONENTS before including Makefile.rules
-include $(LEVEL)/Makefile.config
-
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) MCDisassembler MCParser MC support
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
+TOOL_NO_EXPORTS := 1
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index d930aea1e5..280a1bbd99 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -14,6 +14,7 @@
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstPrinter.h"
@@ -23,16 +24,8 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Target/TargetAsmBackend.h"
-#include "llvm/Target/TargetAsmParser.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetAsmInfo.h" // FIXME.
-#include "llvm/Target/TargetLowering.h" // FIXME.
-#include "llvm/Target/TargetLoweringObjectFile.h" // FIXME.
-#include "llvm/Target/TargetMachine.h" // FIXME.
-#include "llvm/Target/TargetSelect.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
@@ -44,6 +37,8 @@
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
#include "Disassembler.h"
using namespace llvm;
@@ -113,6 +108,12 @@ MCPU("mcpu",
cl::value_desc("cpu-name"),
cl::init(""));
+static cl::list<std::string>
+MAttrs("mattr",
+ cl::CommaSeparated,
+ cl::desc("Target specific attributes (-mattr=help for details)"),
+ cl::value_desc("a1,+a2,-a3,..."));
+
static cl::opt<Reloc::Model>
RelocModel("relocation-model",
cl::desc("Choose relocation model"),
@@ -128,6 +129,22 @@ RelocModel("relocation-model",
"Relocatable external references, non-relocatable code"),
clEnumValEnd));
+static cl::opt<llvm::CodeModel::Model>
+CMModel("code-model",
+ cl::desc("Choose code model"),
+ cl::init(CodeModel::Default),
+ cl::values(clEnumValN(CodeModel::Default, "default",
+ "Target default code model"),
+ clEnumValN(CodeModel::Small, "small",
+ "Small code model"),
+ clEnumValN(CodeModel::Kernel, "kernel",
+ "Kernel code model"),
+ clEnumValN(CodeModel::Medium, "medium",
+ "Medium code model"),
+ clEnumValN(CodeModel::Large, "large",
+ "Large code model"),
+ clEnumValEnd));
+
static cl::opt<bool>
NoInitialTextSection("n", cl::desc("Don't assume assembly file starts "
"in the text section"));
@@ -159,21 +176,42 @@ static const Target *GetTarget(const char *ProgName) {
// Figure out the target triple.
if (TripleName.empty())
TripleName = sys::getHostTriple();
+ Triple TheTriple(Triple::normalize(TripleName));
+
+ const Target *TheTarget = 0;
if (!ArchName.empty()) {
- llvm::Triple TT(TripleName);
- TT.setArchName(ArchName);
- TripleName = TT.str();
- }
+ for (TargetRegistry::iterator it = TargetRegistry::begin(),
+ ie = TargetRegistry::end(); it != ie; ++it) {
+ if (ArchName == it->getName()) {
+ TheTarget = &*it;
+ break;
+ }
+ }
- // Get the target specific parser.
- std::string Error;
- const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
- if (TheTarget)
- return TheTarget;
+ if (!TheTarget) {
+ errs() << ProgName << ": error: invalid target '" << ArchName << "'.\n";
+ return 0;
+ }
- errs() << ProgName << ": error: unable to get target for '" << TripleName
- << "', see --version and --triple.\n";
- return 0;
+ // Adjust the triple to match (if known), otherwise stick with the
+ // module/host triple.
+ Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName);
+ if (Type != Triple::UnknownArch)
+ TheTriple.setArch(Type);
+ } else {
+ // Get the target specific parser.
+ std::string Error;
+ TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
+ if (TheTarget == 0) {
+ errs() << ProgName << ": error: unable to get target for '"
+ << TheTriple.getTriple()
+ << "', see --version and --triple.\n";
+ return 0;
+ }
+ }
+
+ TripleName = TheTriple.getTriple();
+ return TheTarget;
}
static tool_output_file *GetOutputStream() {
@@ -229,7 +267,8 @@ static int AsLexInput(const char *ProgName) {
switch (Tok.getKind()) {
default:
- SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
+ SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning,
+ "unknown token");
Error = true;
break;
case AsmToken::Error:
@@ -329,34 +368,24 @@ static int AssembleInput(const char *ProgName) {
llvm::OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
assert(MRI && "Unable to create target register info!");
- // Package up features to be passed to target/subtarget
- std::string FeaturesStr;
-
- // FIXME: We shouldn't need to do this (and link in codegen).
- // When we split this out, we should do it in a way that makes
- // it straightforward to switch subtargets on the fly (.e.g,
- // the .cpu and .code16 directives).
- OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName,
- MCPU,
- FeaturesStr,
- RelocModel));
-
- if (!TM) {
- errs() << ProgName << ": error: could not create target for triple '"
- << TripleName << "'.\n";
- return 1;
- }
-
- const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
// FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
- MCContext Ctx(*MAI, *MRI, MOFI.get(), tai);
- MOFI->InitMCObjectFileInfo(TripleName, RelocModel, Ctx);
+ MCContext Ctx(*MAI, *MRI, MOFI.get());
+ MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx);
if (SaveTempLabels)
Ctx.setAllowTemporaryLabels(false);
+ // Package up features to be passed to target/subtarget
+ std::string FeaturesStr;
+ if (MAttrs.size()) {
+ SubtargetFeatures Features;
+ for (unsigned i = 0; i != MAttrs.size(); ++i)
+ Features.AddFeature(MAttrs[i]);
+ FeaturesStr = Features.getString();
+ }
+
OwningPtr<tool_output_file> Out(GetOutputStream());
if (!Out)
return 1;
@@ -364,10 +393,6 @@ static int AssembleInput(const char *ProgName) {
formatted_raw_ostream FOS(Out->os());
OwningPtr<MCStreamer> Str;
- const TargetLoweringObjectFile &TLOF =
- TM->getTargetLowering()->getObjFileLowering();
- const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
-
OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
OwningPtr<MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
@@ -375,35 +400,37 @@ static int AssembleInput(const char *ProgName) {
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (FileType == OFT_AssemblyFile) {
MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
+ TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *STI);
MCCodeEmitter *CE = 0;
- TargetAsmBackend *TAB = 0;
+ MCAsmBackend *MAB = 0;
if (ShowEncoding) {
- CE = TheTarget->createCodeEmitter(*MCII, *STI, Ctx);
- TAB = TheTarget->createAsmBackend(TripleName);
+ CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+ MAB = TheTarget->createMCAsmBackend(TripleName);
}
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
/*useLoc*/ true,
- /*useCFI*/ true, IP, CE, TAB,
- ShowInst));
+ /*useCFI*/ true,
+ /*useDwarfDirectory*/ true,
+ IP, CE, MAB, ShowInst));
+
} else if (FileType == OFT_Null) {
Str.reset(createNullStreamer(Ctx));
} else {
assert(FileType == OFT_ObjectFile && "Invalid file type!");
- MCCodeEmitter *CE = TheTarget->createCodeEmitter(*MCII, *STI, Ctx);
- TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);
- Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
- FOS, CE, RelaxAll,
- NoExecStack));
+ MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+ MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName);
+ Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
+ FOS, CE, RelaxAll,
+ NoExecStack));
}
if (EnableLogging) {
Str.reset(createLoggingStreamer(Str.take(), errs()));
}
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
- *Str.get(), *MAI));
- OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*STI, *Parser));
+ OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
+ *Str.get(), *MAI));
+ OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser));
if (!TAP) {
errs() << ProgName
<< ": error: this target does not support assembly parsing.\n";
@@ -441,7 +468,16 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) {
Res =
Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os());
} else {
- Res = Disassembler::disassemble(*TheTarget, TripleName,
+ // Package up features to be passed to target/subtarget
+ std::string FeaturesStr;
+ if (MAttrs.size()) {
+ SubtargetFeatures Features;
+ for (unsigned i = 0; i != MAttrs.size(); ++i)
+ Features.AddFeature(MAttrs[i]);
+ FeaturesStr = Features.getString();
+ }
+
+ Res = Disassembler::disassemble(*TheTarget, TripleName, MCPU, FeaturesStr,
*Buffer.take(), Out->os());
}
@@ -460,14 +496,7 @@ int main(int argc, char **argv) {
// Initialize targets and assembly printers/parsers.
llvm::InitializeAllTargetInfos();
- // FIXME: We shouldn't need to initialize the Target(Machine)s.
- llvm::InitializeAllTargets();
- llvm::InitializeAllMCAsmInfos();
- llvm::InitializeAllMCCodeGenInfos();
- llvm::InitializeAllMCInstrInfos();
- llvm::InitializeAllMCRegisterInfos();
- llvm::InitializeAllMCSubtargetInfos();
- llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllDisassemblers();
@@ -488,4 +517,3 @@ int main(int argc, char **argv) {
return 0;
}
-