llvm-mc.cpp revision a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1
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:
8314ee48a5bae352780b767a14bd97e8e91800a95bChris Lattner      Lexer.PrintMessage(Lexer.getLoc(), "driver: unknown token");
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;
1014651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::EndOfStatement: outs() << "EndOfStatement\n"; break;
102a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Colon:  outs() << "Colon\n"; break;
103a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Plus:   outs() << "Plus\n"; break;
104a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Minus:  outs() << "Minus\n"; break;
10574ec1a3b115a889e1a70dd22d8dcc6a5e753a5d2Chris Lattner    case asmtok::Tilde:  outs() << "Tilde\n"; break;
1064651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Slash:  outs() << "Slash\n"; break;
1074651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::LParen: outs() << "LParen\n"; break;
1084651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::RParen: outs() << "RParen\n"; break;
1094651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Star:   outs() << "Star\n"; break;
1104651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Comma:  outs() << "Comma\n"; break;
1114651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Dollar: outs() << "Dollar\n"; break;
112a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    }
113a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
114a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    Tok = Lexer.Lex();
115a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  }
116f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
11727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  return Error;
118b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner}
119b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
12027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AssembleInput(const char *ProgName) {
12127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  std::string ErrorMessage;
12227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
12327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                                                      &ErrorMessage);
12427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  if (Buffer == 0) {
12527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    errs() << ProgName << ": ";
12627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    if (ErrorMessage.size())
12727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      errs() << ErrorMessage << "\n";
12827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    else
12927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      errs() << "input file didn't read correctly.\n";
13027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return 1;
13127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  }
13227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
13327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SourceMgr SrcMgr;
13427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
13527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
13627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
13727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
13827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // Record the location of the include directories so that the lexer can find
13927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // it later.
14027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.setIncludeDirs(IncludeDirs);
14127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
142cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner  MCContext Ctx;
143cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner  OwningPtr<MCStreamer> Str(createAsmStreamer(Ctx, outs()));
144a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar
145a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar  // FIXME: Target hook & command line option for initial section.
146a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar  Str.get()->SwitchSection(Ctx.GetSection("__TEXT,__text,regular,pure_instructions"));
147a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar
148c69485e34d57e17fe2c3acab64e519d6a6945197Chris Lattner  AsmParser Parser(SrcMgr, Ctx, *Str.get());
14927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  return Parser.Run();
15027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner}
15127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
152b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
153b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerint main(int argc, char **argv) {
154b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Print a stack trace if we signal out.
155b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  sys::PrintStackTraceOnErrorSignal();
156b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  PrettyStackTraceProgram X(argc, argv);
157b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
158b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
159b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
160b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  switch (Action) {
161b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  default:
16227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  case AC_AsLex:
16327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return AsLexInput(argv[0]);
164b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  case AC_Assemble:
165b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner    return AssembleInput(argv[0]);
166b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  }
167b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
168f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  return 0;
169f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner}
170f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
171