llvm-mc.cpp revision 165e8344d833147268810bbec18276dafe0122b9
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"
16cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/MC/MCStreamer.h"
17cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/ADT/OwningPtr.h"
18f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/CommandLine.h"
19f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/ManagedStatic.h"
20f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/MemoryBuffer.h"
21f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
22b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner#include "llvm/Support/SourceMgr.h"
23f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/raw_ostream.h"
24f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/System/Signals.h"
2527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner#include "AsmParser.h"
26f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerusing namespace llvm;
27f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
28f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string>
29f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerInputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
30f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
31f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string>
32f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerOutputFilename("o", cl::desc("Output filename"),
33f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner               cl::value_desc("filename"));
34f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
35b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::list<std::string>
36b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerIncludeDirs("I", cl::desc("Directory of include files"),
37b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner            cl::value_desc("directory"), cl::Prefix);
38f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
39b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerenum ActionType {
4027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  AC_AsLex,
41b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  AC_Assemble
42b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner};
43f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
44b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::opt<ActionType>
45b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerAction(cl::desc("Action to perform:"),
4627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner       cl::init(AC_Assemble),
4727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner       cl::values(clEnumValN(AC_AsLex, "as-lex",
4827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                             "Lex tokens from a .s file"),
4927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                  clEnumValN(AC_Assemble, "assemble",
50b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                             "Assemble a .s file (default)"),
51b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                  clEnumValEnd));
52f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
5327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AsLexInput(const char *ProgName) {
54b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  std::string ErrorMessage;
55b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
56b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                                                      &ErrorMessage);
57f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  if (Buffer == 0) {
58b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner    errs() << ProgName << ": ";
59f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    if (ErrorMessage.size())
60f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner      errs() << ErrorMessage << "\n";
61f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    else
62f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner      errs() << "input file didn't read correctly.\n";
63f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    return 1;
64f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  }
65b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
66b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SourceMgr SrcMgr;
67b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
68b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
69b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
70b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
71b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Record the location of the include directories so that the lexer can find
72b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // it later.
73b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SrcMgr.setIncludeDirs(IncludeDirs);
74a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
75a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  AsmLexer Lexer(SrcMgr);
76f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
7727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  bool Error = false;
7827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
79a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  asmtok::TokKind Tok = Lexer.Lex();
80a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  while (Tok != asmtok::Eof) {
81a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    switch (Tok) {
8227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    default:
833fb7683bec8c8edb24e80c95f3b0668c6ecc0ae6Daniel Dunbar      Lexer.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
8427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      Error = true;
8527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      break;
864651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Error:
8727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      Error = true; // error already printed.
884651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      break;
89a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Identifier:
90a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      outs() << "identifier: " << Lexer.getCurStrVal() << '\n';
91a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      break;
924651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Register:
934651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      outs() << "register: " << Lexer.getCurStrVal() << '\n';
944651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      break;
9510a907d70fb54c40eecabb889e81c79b44092221Chris Lattner    case asmtok::String:
9610a907d70fb54c40eecabb889e81c79b44092221Chris Lattner      outs() << "string: " << Lexer.getCurStrVal() << '\n';
9710a907d70fb54c40eecabb889e81c79b44092221Chris Lattner      break;
98a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::IntVal:
99a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      outs() << "int: " << Lexer.getCurIntVal() << '\n';
100a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      break;
101165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar
102165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Amp:            outs() << "Amp\n"; break;
103165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::AmpAmp:         outs() << "AmpAmp\n"; break;
104165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Caret:          outs() << "Caret\n"; break;
10587380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner    case asmtok::Colon:          outs() << "Colon\n"; break;
10687380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner    case asmtok::Comma:          outs() << "Comma\n"; break;
10787380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner    case asmtok::Dollar:         outs() << "Dollar\n"; break;
108165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::EndOfStatement: outs() << "EndOfStatement\n"; break;
109165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Eof:            outs() << "Eof\n"; break;
11087380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner    case asmtok::Equal:          outs() << "Equal\n"; break;
11187380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner    case asmtok::EqualEqual:     outs() << "EqualEqual\n"; break;
112165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Exclaim:        outs() << "Exclaim\n"; break;
113165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::ExclaimEqual:   outs() << "ExclaimEqual\n"; break;
114165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Greater:        outs() << "Greater\n"; break;
115165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::GreaterEqual:   outs() << "GreaterEqual\n"; break;
116165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::GreaterGreater: outs() << "GreaterGreater\n"; break;
117165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::LParen:         outs() << "LParen\n"; break;
118165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Less:           outs() << "Less\n"; break;
119165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::LessEqual:      outs() << "LessEqual\n"; break;
120165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::LessGreater:    outs() << "LessGreater\n"; break;
121165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::LessLess:       outs() << "LessLess\n"; break;
122165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Minus:          outs() << "Minus\n"; break;
123165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Percent:        outs() << "Percent\n"; break;
12487380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner    case asmtok::Pipe:           outs() << "Pipe\n"; break;
12587380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner    case asmtok::PipePipe:       outs() << "PipePipe\n"; break;
126165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Plus:           outs() << "Plus\n"; break;
127165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::RParen:         outs() << "RParen\n"; break;
128165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Slash:          outs() << "Slash\n"; break;
129165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Star:           outs() << "Star\n"; break;
130165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar    case asmtok::Tilde:          outs() << "Tilde\n"; break;
131a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    }
132a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
133a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    Tok = Lexer.Lex();
134a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  }
135f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
13627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  return Error;
137b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner}
138b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
13927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AssembleInput(const char *ProgName) {
14027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  std::string ErrorMessage;
14127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
14227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                                                      &ErrorMessage);
14327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  if (Buffer == 0) {
14427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    errs() << ProgName << ": ";
14527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    if (ErrorMessage.size())
14627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      errs() << ErrorMessage << "\n";
14727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    else
14827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      errs() << "input file didn't read correctly.\n";
14927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return 1;
15027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  }
15127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
15227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SourceMgr SrcMgr;
15327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
15427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
15527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
15627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
15727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // Record the location of the include directories so that the lexer can find
15827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // it later.
15927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.setIncludeDirs(IncludeDirs);
16027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
161cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner  MCContext Ctx;
162cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner  OwningPtr<MCStreamer> Str(createAsmStreamer(Ctx, outs()));
163a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar
164a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar  // FIXME: Target hook & command line option for initial section.
165a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar  Str.get()->SwitchSection(Ctx.GetSection("__TEXT,__text,regular,pure_instructions"));
166a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar
167c69485e34d57e17fe2c3acab64e519d6a6945197Chris Lattner  AsmParser Parser(SrcMgr, Ctx, *Str.get());
16827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  return Parser.Run();
16927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner}
17027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
171b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
172b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerint main(int argc, char **argv) {
173b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Print a stack trace if we signal out.
174b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  sys::PrintStackTraceOnErrorSignal();
175b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  PrettyStackTraceProgram X(argc, argv);
176b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
177b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
178b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
179b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  switch (Action) {
180b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  default:
18127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  case AC_AsLex:
18227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return AsLexInput(argv[0]);
183b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  case AC_Assemble:
184b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner    return AssembleInput(argv[0]);
185b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  }
186b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
187f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  return 0;
188f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner}
189f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
190