SparcV8 removed until it grows up becomes a mature backend.
[oota-llvm.git] / tools / llc / llc.cpp
1 //===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This is the llc code generator.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Bytecode/Reader.h"
15 #include "llvm/Target/TargetMachineImpls.h"
16 #include "llvm/Target/TargetMachine.h"
17 #include "llvm/Transforms/Scalar.h"
18 #include "llvm/Module.h"
19 #include "llvm/PassManager.h"
20 #include "llvm/Pass.h"
21 #include "Support/CommandLine.h"
22 #include "Support/Signals.h"
23 #include <memory>
24 #include <fstream>
25
26 using namespace llvm;
27
28 // General options for llc.  Other pass-specific options are specified
29 // within the corresponding llc passes, and target-specific options
30 // and back-end code generation options are specified with the target machine.
31 // 
32 static cl::opt<std::string>
33 InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
34
35 static cl::opt<std::string>
36 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
37
38 static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
39
40 enum ArchName { noarch, X86, SparcV9, PowerPC, CBackend };
41
42 static cl::opt<ArchName>
43 Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
44      cl::values(clEnumValN(X86,      "x86",     "  IA-32 (Pentium and above)"),
45                 clEnumValN(SparcV9,  "sparcv9", "  SPARC V9"),
46                 clEnumValN(PowerPC,  "powerpc", "  PowerPC (experimental)"),
47                 clEnumValN(CBackend, "c",       "  C backend"),
48                 0),
49      cl::init(noarch));
50
51 // GetFileNameRoot - Helper function to get the basename of a filename...
52 static inline std::string
53 GetFileNameRoot(const std::string &InputFilename)
54 {
55   std::string IFN = InputFilename;
56   std::string outputFilename;
57   int Len = IFN.length();
58   if ((Len > 2) &&
59       IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
60     outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
61   } else {
62     outputFilename = IFN;
63   }
64   return outputFilename;
65 }
66
67
68 // main - Entry point for the llc compiler.
69 //
70 int main(int argc, char **argv) {
71   cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
72   PrintStackTraceOnErrorSignal();
73
74   // Load the module to be compiled...
75   std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
76   if (M.get() == 0) {
77     std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
78     return 1;
79   }
80   Module &mod = *M.get();
81
82   // Allocate target machine.  First, check whether the user has
83   // explicitly specified an architecture to compile for.
84   TargetMachine* (*TargetMachineAllocator)(const Module&,
85                                            IntrinsicLowering *) = 0;
86   switch (Arch) {
87   case CBackend:
88     TargetMachineAllocator = allocateCTargetMachine;
89     break;
90   case X86:
91     TargetMachineAllocator = allocateX86TargetMachine;
92     break;
93   case SparcV9:
94     TargetMachineAllocator = allocateSparcV9TargetMachine;
95     break;
96   case PowerPC:
97     TargetMachineAllocator = allocatePowerPCTargetMachine;
98     break;
99   default:
100     // Decide what the default target machine should be, by looking at
101     // the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
102     // SPARCV9) is kind of gross, but it will work until we have more
103     // sophisticated target information to work from.
104     if (mod.getEndianness()  == Module::LittleEndian &&
105         mod.getPointerSize() == Module::Pointer32) { 
106       TargetMachineAllocator = allocateX86TargetMachine;
107     } else if (mod.getEndianness() == Module::BigEndian &&
108         mod.getPointerSize() == Module::Pointer32) { 
109       TargetMachineAllocator = allocatePowerPCTargetMachine;
110     } else if (mod.getEndianness()  == Module::BigEndian &&
111                mod.getPointerSize() == Module::Pointer64) { 
112       TargetMachineAllocator = allocateSparcV9TargetMachine;
113     } else {
114       // If the module is target independent, favor a target which matches the
115       // current build system.
116 #if defined(i386) || defined(__i386__) || defined(__x86__)
117       TargetMachineAllocator = allocateX86TargetMachine;
118 #elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
119       TargetMachineAllocator = allocateSparcV9TargetMachine;
120 #elif defined(__POWERPC__) || defined(__ppc__) || defined(__APPLE__)
121       TargetMachineAllocator = allocatePowerPCTargetMachine;
122 #else
123       std::cerr << argv[0] << ": module does not specify a target to use.  "
124                 << "You must use the -march option.  If no native target is "
125                 << "available, use -march=c to emit C code.\n";
126       return 1;
127 #endif
128     } 
129     break;
130   }
131   std::auto_ptr<TargetMachine> target(TargetMachineAllocator(mod, 0));
132   assert(target.get() && "Could not allocate target machine!");
133   TargetMachine &Target = *target.get();
134   const TargetData &TD = Target.getTargetData();
135
136   // Build up all of the passes that we want to do to the module...
137   PassManager Passes;
138
139   Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
140                             TD.getPointerAlignment(), TD.getDoubleAlignment()));
141
142   // Figure out where we are going to send the output...
143   std::ostream *Out = 0;
144   if (OutputFilename != "") {
145     if (OutputFilename != "-") {
146       // Specified an output filename?
147       if (!Force && std::ifstream(OutputFilename.c_str())) {
148         // If force is not specified, make sure not to overwrite a file!
149         std::cerr << argv[0] << ": error opening '" << OutputFilename
150                   << "': file exists!\n"
151                   << "Use -f command line argument to force output\n";
152         return 1;
153       }
154       Out = new std::ofstream(OutputFilename.c_str());
155
156       // Make sure that the Out file gets unlinked from the disk if we get a
157       // SIGINT
158       RemoveFileOnSignal(OutputFilename);
159     } else {
160       Out = &std::cout;
161     }
162   } else {
163     if (InputFilename == "-") {
164       OutputFilename = "-";
165       Out = &std::cout;
166     } else {
167       OutputFilename = GetFileNameRoot(InputFilename); 
168
169       if (Arch != CBackend)
170         OutputFilename += ".s";
171       else
172         OutputFilename += ".cbe.c";
173       
174       if (!Force && std::ifstream(OutputFilename.c_str())) {
175         // If force is not specified, make sure not to overwrite a file!
176         std::cerr << argv[0] << ": error opening '" << OutputFilename
177                   << "': file exists!\n"
178                   << "Use -f command line argument to force output\n";
179         return 1;
180       }
181       
182       Out = new std::ofstream(OutputFilename.c_str());
183       if (!Out->good()) {
184         std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
185         delete Out;
186         return 1;
187       }
188       
189       // Make sure that the Out file gets unlinked from the disk if we get a
190       // SIGINT
191       RemoveFileOnSignal(OutputFilename);
192     }
193   }
194
195   // Ask the target to add backend passes as necessary
196   if (Target.addPassesToEmitAssembly(Passes, *Out)) {
197     std::cerr << argv[0] << ": target '" << Target.getName()
198               << "' does not support static compilation!\n";
199     if (Out != &std::cout) delete Out;
200     // And the Out file is empty and useless, so remove it now.
201     std::remove(OutputFilename.c_str());
202     return 1;
203   } else {
204     // Run our queue of passes all at once now, efficiently.
205     Passes.run(*M.get());
206   }
207
208   // Delete the ostream if it's not a stdout stream
209   if (Out != &std::cout) delete Out;
210
211   return 0;
212 }