llvm-mc.cpp revision 27aa7d259b416a9d1bf837ed2c3c11463367b11c
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
15f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/CommandLine.h"
16f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/ManagedStatic.h"
17f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/MemoryBuffer.h"
18f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
19b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner#include "llvm/Support/SourceMgr.h"
20f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/raw_ostream.h"
21f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/System/Signals.h"
2227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner#include "AsmParser.h"
23f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerusing namespace llvm;
24f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
25f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string>
26f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerInputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
27f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
28f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string>
29f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerOutputFilename("o", cl::desc("Output filename"),
30f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner               cl::value_desc("filename"));
31f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
32b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::list<std::string>
33b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerIncludeDirs("I", cl::desc("Directory of include files"),
34b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner            cl::value_desc("directory"), cl::Prefix);
35f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
36b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerenum ActionType {
3727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  AC_AsLex,
38b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  AC_Assemble
39b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner};
40f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
41b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::opt<ActionType>
42b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerAction(cl::desc("Action to perform:"),
4327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner       cl::init(AC_Assemble),
4427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner       cl::values(clEnumValN(AC_AsLex, "as-lex",
4527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                             "Lex tokens from a .s file"),
4627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                  clEnumValN(AC_Assemble, "assemble",
47b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                             "Assemble a .s file (default)"),
48b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                  clEnumValEnd));
49f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
5027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AsLexInput(const char *ProgName) {
51b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  std::string ErrorMessage;
52b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
53b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner                                                      &ErrorMessage);
54f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  if (Buffer == 0) {
55b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner    errs() << ProgName << ": ";
56f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    if (ErrorMessage.size())
57f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner      errs() << ErrorMessage << "\n";
58f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    else
59f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner      errs() << "input file didn't read correctly.\n";
60f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner    return 1;
61f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  }
62b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
63b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SourceMgr SrcMgr;
64b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
65b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
66b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
67b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
68b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Record the location of the include directories so that the lexer can find
69b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // it later.
70b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  SrcMgr.setIncludeDirs(IncludeDirs);
71a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
72a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  AsmLexer Lexer(SrcMgr);
73f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
7427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  bool Error = false;
7527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
76a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  asmtok::TokKind Tok = Lexer.Lex();
77a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  while (Tok != asmtok::Eof) {
78a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    switch (Tok) {
7927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    default:
8027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      Lexer.PrintError(Lexer.getLoc(), "driver: unknown token");
8127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      Error = true;
8227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      break;
834651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Error:
8427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      Error = true; // error already printed.
854651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      break;
86a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Identifier:
87a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      outs() << "identifier: " << Lexer.getCurStrVal() << '\n';
88a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      break;
894651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Register:
904651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      outs() << "register: " << Lexer.getCurStrVal() << '\n';
914651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      break;
9210a907d70fb54c40eecabb889e81c79b44092221Chris Lattner    case asmtok::String:
9310a907d70fb54c40eecabb889e81c79b44092221Chris Lattner      outs() << "string: " << Lexer.getCurStrVal() << '\n';
9410a907d70fb54c40eecabb889e81c79b44092221Chris Lattner      break;
95a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::IntVal:
96a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      outs() << "int: " << Lexer.getCurIntVal() << '\n';
97a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      break;
984651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::EndOfStatement: outs() << "EndOfStatement\n"; break;
99a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Colon:  outs() << "Colon\n"; break;
100a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Plus:   outs() << "Plus\n"; break;
101a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    case asmtok::Minus:  outs() << "Minus\n"; break;
1024651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Slash:  outs() << "Slash\n"; break;
1034651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::LParen: outs() << "LParen\n"; break;
1044651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::RParen: outs() << "RParen\n"; break;
1054651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Star:   outs() << "Star\n"; break;
1064651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Comma:  outs() << "Comma\n"; break;
1074651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case asmtok::Dollar: outs() << "Dollar\n"; break;
108a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    }
109a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
110a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    Tok = Lexer.Lex();
111a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  }
112f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
11327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  return Error;
114b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner}
115b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
11627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AssembleInput(const char *ProgName) {
11727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  std::string ErrorMessage;
11827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
11927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner                                                      &ErrorMessage);
12027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  if (Buffer == 0) {
12127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    errs() << ProgName << ": ";
12227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    if (ErrorMessage.size())
12327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      errs() << ErrorMessage << "\n";
12427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    else
12527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      errs() << "input file didn't read correctly.\n";
12627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return 1;
12727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  }
12827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
12927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SourceMgr SrcMgr;
13027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
13127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
13227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
13327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
13427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // Record the location of the include directories so that the lexer can find
13527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  // it later.
13627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  SrcMgr.setIncludeDirs(IncludeDirs);
13727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
13827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  AsmParser Parser(SrcMgr);
13927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  return Parser.Run();
14027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner}
14127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner
142b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
143b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerint main(int argc, char **argv) {
144b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  // Print a stack trace if we signal out.
145b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  sys::PrintStackTraceOnErrorSignal();
146b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  PrettyStackTraceProgram X(argc, argv);
147b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
148b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
149b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
150b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  switch (Action) {
151b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  default:
15227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner  case AC_AsLex:
15327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return AsLexInput(argv[0]);
154b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  case AC_Assemble:
155b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner    return AssembleInput(argv[0]);
156b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner  }
157b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner
158f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner  return 0;
159f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner}
160f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner
161