llvm-mc.cpp revision 4a0abd80f18f9c2a10bf5b14cd6731d51972a426
1bb4688a9cf385ccada90ebeb04b3ba5827bf213dChris Lattner//===-- llvm-mc.cpp - Machine Code Hacking Driver -------------------------===//
2f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//
3f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//                     The LLVM Compiler Infrastructure
4f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//
5f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// This file is distributed under the University of Illinois Open Source
6f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// License. See LICENSE.TXT for details.
7f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//
8f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//===----------------------------------------------------------------------===//
9f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//
10bb4688a9cf385ccada90ebeb04b3ba5827bf213dChris Lattner// This utility is a simple driver that allows command line hacking on machine
11bb4688a9cf385ccada90ebeb04b3ba5827bf213dChris Lattner// code.
12f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//
13f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//===----------------------------------------------------------------------===//
14f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
15cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/MC/MCContext.h"
164a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbar#include "llvm/MC/MCCodeEmitter.h"
17f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
18cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/MC/MCStreamer.h"
19cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/ADT/OwningPtr.h"
20c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar#include "llvm/CodeGen/AsmPrinter.h"
21f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/CommandLine.h"
22c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar#include "llvm/Support/FormattedStream.h"
23f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/ManagedStatic.h"
24f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/MemoryBuffer.h"
25f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
26b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner#include "llvm/Support/SourceMgr.h"
27f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/raw_ostream.h"
28f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/System/Signals.h"
29a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar#include "llvm/Target/TargetAsmParser.h"
30b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
31b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar#include "llvm/Target/TargetSelect.h"
3227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner#include "AsmParser.h"
33f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerusing namespace llvm;
34f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
35f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string>
36f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerInputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
37f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
38f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string>
39f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerOutputFilename("o", cl::desc("Output filename"),
40f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner               cl::value_desc("filename"));
41f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
42fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarenum OutputFileType {
43fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  OFT_AssemblyFile,
44fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  OFT_ObjectFile
45fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar};
46fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarstatic cl::opt<OutputFileType>
47fb4a6b397665df011348ade24a8e38d2219f095aDaniel DunbarFileType("filetype", cl::init(OFT_AssemblyFile),
48fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  cl::desc("Choose an output file type:"),
49fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  cl::values(
50fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar       clEnumValN(OFT_AssemblyFile, "asm",
51fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                  "Emit an assembly ('.s') file"),
52fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar       clEnumValN(OFT_ObjectFile, "obj",
53fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar                  "Emit a native object ('.o') file"),
54fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar       clEnumValEnd));
55fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
56bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbarstatic cl::opt<bool>
57baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan GohmanForce("f", cl::desc("Enable binary output on terminals"));
58bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar
59b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::list<std::string>
60b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerIncludeDirs("I", cl::desc("Directory of include files"),
61b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner            cl::value_desc("directory"), cl::Prefix);
62f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
63b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbarstatic cl::opt<std::string>
648977d087c693fd581db82bcff134d12da0f48bd3Daniel DunbarTripleName("triple", cl::desc("Target triple to assemble for,"
65b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar                          "see -version for available targets"),
66867aadfedfb6d9b64fd5da1ca67850a992605a3bDaniel Dunbar       cl::init(LLVM_HOSTTRIPLE));
67b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar
68b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerenum ActionType {
6927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  AC_AsLex,
70b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  AC_Assemble
71b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner};
72f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
73b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::opt<ActionType>
74b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerAction(cl::desc("Action to perform:"),
7527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner       cl::init(AC_Assemble),
7627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner       cl::values(clEnumValN(AC_AsLex, "as-lex",
7727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                             "Lex tokens from a .s file"),
7827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                  clEnumValN(AC_Assemble, "assemble",
79b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                             "Assemble a .s file (default)"),
80b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                  clEnumValEnd));
81f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
8227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AsLexInput(const char *ProgName) {
83b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  std::string ErrorMessage;
84b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
85b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                                                      &ErrorMessage);
86f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  if (Buffer == 0) {
87b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner    errs() << ProgName << ": ";
88f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    if (ErrorMessage.size())
89f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner      errs() << ErrorMessage << "\n";
90f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    else
91f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner      errs() << "input file didn't read correctly.\n";
92f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    return 1;
93f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  }
94b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
95b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SourceMgr SrcMgr;
96b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
97b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
98b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
99b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
100b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Record the location of the include directories so that the lexer can find
101b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // it later.
102b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SrcMgr.setIncludeDirs(IncludeDirs);
103a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
104a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  AsmLexer Lexer(SrcMgr);
105f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
10627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  bool Error = false;
10727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
108a3c924f83aefd4c883ed17a200876d258e0ad1e2Daniel Dunbar  while (Lexer.Lex().isNot(AsmToken::Eof)) {
109a3c924f83aefd4c883ed17a200876d258e0ad1e2Daniel Dunbar    switch (Lexer.getKind()) {
11027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    default:
1113fb7683bec8c8edb24e80c95f3b0668c6ecc0ae6Daniel Dunbar      Lexer.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
11227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      Error = true;
11327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      break;
1143f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Error:
11527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      Error = true; // error already printed.
1164651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      break;
1173f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Identifier:
118419adedaa1638fbe4e078c997f81e94327ebff5aDaniel Dunbar      outs() << "identifier: " << Lexer.getTok().getString() << '\n';
119a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      break;
1203f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Register:
121419adedaa1638fbe4e078c997f81e94327ebff5aDaniel Dunbar      outs() << "register: " << Lexer.getTok().getString() << '\n';
1224651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      break;
1233f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::String:
124419adedaa1638fbe4e078c997f81e94327ebff5aDaniel Dunbar      outs() << "string: " << Lexer.getTok().getString() << '\n';
12510a907d70fb54c40eecabb889e81c79b44092221Chris Lattner      break;
1263f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Integer:
127419adedaa1638fbe4e078c997f81e94327ebff5aDaniel Dunbar      outs() << "int: " << Lexer.getTok().getString() << '\n';
128a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      break;
129165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar
1303f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Amp:            outs() << "Amp\n"; break;
1313f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::AmpAmp:         outs() << "AmpAmp\n"; break;
1323f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Caret:          outs() << "Caret\n"; break;
1333f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Colon:          outs() << "Colon\n"; break;
1343f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Comma:          outs() << "Comma\n"; break;
1353f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Dollar:         outs() << "Dollar\n"; break;
1363f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::EndOfStatement: outs() << "EndOfStatement\n"; break;
1373f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Eof:            outs() << "Eof\n"; break;
1383f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Equal:          outs() << "Equal\n"; break;
1393f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::EqualEqual:     outs() << "EqualEqual\n"; break;
1403f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Exclaim:        outs() << "Exclaim\n"; break;
1413f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::ExclaimEqual:   outs() << "ExclaimEqual\n"; break;
1423f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Greater:        outs() << "Greater\n"; break;
1433f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::GreaterEqual:   outs() << "GreaterEqual\n"; break;
1443f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::GreaterGreater: outs() << "GreaterGreater\n"; break;
1453f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::LParen:         outs() << "LParen\n"; break;
1463f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Less:           outs() << "Less\n"; break;
1473f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::LessEqual:      outs() << "LessEqual\n"; break;
1483f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::LessGreater:    outs() << "LessGreater\n"; break;
1493f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::LessLess:       outs() << "LessLess\n"; break;
1503f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Minus:          outs() << "Minus\n"; break;
1513f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Percent:        outs() << "Percent\n"; break;
1523f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Pipe:           outs() << "Pipe\n"; break;
1533f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::PipePipe:       outs() << "PipePipe\n"; break;
1543f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Plus:           outs() << "Plus\n"; break;
1553f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::RParen:         outs() << "RParen\n"; break;
1563f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Slash:          outs() << "Slash\n"; break;
1573f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Star:           outs() << "Star\n"; break;
1583f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    case AsmToken::Tilde:          outs() << "Tilde\n"; break;
159a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    }
160a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  }
161f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
16227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  return Error;
163b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner}
164b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
165c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbarstatic const Target *GetTarget(const char *ProgName) {
166b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar  // Get the target specific parser.
167b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar  std::string Error;
1684bd03abe593222b26e84066223feb321bf738625Daniel Dunbar  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
169c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  if (TheTarget)
170c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar    return TheTarget;
171b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar
172c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  errs() << ProgName << ": error: unable to get target for '" << TripleName
173c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar         << "', see --version and --triple.\n";
174a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar  return 0;
175a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar}
176b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar
177c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbarstatic formatted_raw_ostream *GetOutputStream() {
17817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (OutputFilename == "")
17917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    OutputFilename = "-";
180bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar
181bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar  // Make sure that the Out file gets unlinked from the disk if we get a
18217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  // SIGINT.
18317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (OutputFilename != "-")
18417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
185bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar
186bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar  std::string Err;
18717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  raw_fd_ostream *Out = new raw_fd_ostream(OutputFilename.c_str(), Err,
188baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan Gohman                                           raw_fd_ostream::F_Binary);
189bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar  if (!Err.empty()) {
190bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar    errs() << Err << '\n';
191bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar    delete Out;
192bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar    return 0;
193bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar  }
194bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar
195c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM);
196bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar}
197bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar
198a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbarstatic int AssembleInput(const char *ProgName) {
199c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  const Target *TheTarget = GetTarget(ProgName);
200c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  if (!TheTarget)
201c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar    return 1;
202c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar
203a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar  std::string Error;
204a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error);
20527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  if (Buffer == 0) {
20627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    errs() << ProgName << ": ";
207a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar    if (Error.size())
208a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar      errs() << Error << "\n";
20927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    else
21027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      errs() << "input file didn't read correctly.\n";
21127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return 1;
21227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  }
21327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
21427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SourceMgr SrcMgr;
21527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
21612a8a447a4ca5b939f255ae92e7fef490344593aDaniel Dunbar  // Tell SrcMgr about this buffer, which is what the parser will pick up.
21727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
21827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
21927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // Record the location of the include directories so that the lexer can find
22027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // it later.
22127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.setIncludeDirs(IncludeDirs);
22227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
223cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner  MCContext Ctx;
224c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  formatted_raw_ostream *Out = GetOutputStream();
225bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar  if (!Out)
226bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar    return 1;
227c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar
228c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar
229c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  // FIXME: We shouldn't need to do this (and link in codegen).
230c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, ""));
231c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar
232f3ce009fcb0a04a245c437d86657e9bd61ecc18fChris Lattner  if (!TM) {
233f3ce009fcb0a04a245c437d86657e9bd61ecc18fChris Lattner    errs() << ProgName << ": error: could not create target for triple '"
234f3ce009fcb0a04a245c437d86657e9bd61ecc18fChris Lattner           << TripleName << "'.\n";
235f3ce009fcb0a04a245c437d86657e9bd61ecc18fChris Lattner    return 1;
236c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  }
237c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar
238fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  OwningPtr<AsmPrinter> AP;
2394a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbar  OwningPtr<MCCodeEmitter> CE;
240fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  OwningPtr<MCStreamer> Str;
241f3ce009fcb0a04a245c437d86657e9bd61ecc18fChris Lattner
242fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  if (FileType == OFT_AssemblyFile) {
243af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner    const MCAsmInfo *TAI = TheTarget->createAsmInfo(TripleName);
244fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar    assert(TAI && "Unable to create target asm info!");
245fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar
246fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar    AP.reset(TheTarget->createAsmPrinter(*Out, *TM, TAI, true));
2474a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbar    CE.reset(TheTarget->createCodeEmitter(*TM, TAI));
2484a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbar    Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get(), CE.get()));
249fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  } else {
250fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar    assert(FileType == OFT_ObjectFile && "Invalid file type!");
251fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar    Str.reset(createMachOStreamer(Ctx, *Out));
252fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar  }
253a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar
254a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar  AsmParser Parser(SrcMgr, Ctx, *Str.get());
255c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(Parser));
256c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  if (!TAP) {
257c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar    errs() << ProgName
258c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar           << ": error: this target does not support assembly parsing.\n";
259a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar    return 1;
260c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  }
261c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar
26216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  Parser.setTargetParser(*TAP.get());
263bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar
264bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar  int Res = Parser.Run();
265c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  if (Out != &fouts())
266bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar    delete Out;
267bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar
268bfc0f34e34c4278b49d70b7a20e1b87cbce0a710Daniel Dunbar  return Res;
26927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner}
27027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
271b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
272b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerint main(int argc, char **argv) {
273b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Print a stack trace if we signal out.
274b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  sys::PrintStackTraceOnErrorSignal();
275b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  PrettyStackTraceProgram X(argc, argv);
276b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
277b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar
278c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  // Initialize targets and assembly printers/parsers.
279b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar  llvm::InitializeAllTargetInfos();
280c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  // FIXME: We shouldn't need to initialize the Target(Machine)s.
281c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  llvm::InitializeAllTargets();
282c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar  llvm::InitializeAllAsmPrinters();
283b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar  llvm::InitializeAllAsmParsers();
284b4b53e5c13167925d6315a6f57c7b863e4e2b704Daniel Dunbar
285b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
286b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
287b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  switch (Action) {
288b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  default:
28927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  case AC_AsLex:
29027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return AsLexInput(argv[0]);
291b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  case AC_Assemble:
292b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner    return AssembleInput(argv[0]);
293b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  }
294b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
295f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  return 0;
296f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner}
297f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
298