diff --git a/tools/gccld/GenerateCode.cpp b/tools/gccld/GenerateCode.cpp index d2c0f3dd31a..dad1bc2442f 100644 --- a/tools/gccld/GenerateCode.cpp +++ b/tools/gccld/GenerateCode.cpp @@ -25,7 +25,6 @@ #include "llvm/Transforms/Utils/Linker.h" #include "Support/SystemUtils.h" #include "Support/CommandLine.h" - using namespace llvm; namespace { @@ -182,6 +181,23 @@ GenerateAssembly(const std::string &OutputFilename, return ExecWait(cmd, envp); } +/// GenerateAssembly - generates a native assembly language source file from the +/// specified bytecode file. +int GenerateCFile(const std::string &OutputFile, const std::string &InputFile, + const std::string &llc, char ** const envp) { + // Run LLC to convert the bytecode file into C. + const char *cmd[8]; + + cmd[0] = llc.c_str(); + cmd[1] = "-march=c"; + cmd[2] = "-f"; + cmd[3] = "-o"; + cmd[4] = OutputFile.c_str(); + cmd[5] = InputFile.c_str(); + cmd[6] = NULL; + return ExecWait(cmd, envp); +} + /// GenerateNative - generates a native assembly language source file from the /// specified assembly source file. /// @@ -230,6 +246,7 @@ GenerateNative(const std::string &OutputFilename, // and linker because we don't know where to put the _start symbol. // GCC mysteriously knows how to do it. cmd.push_back(gcc.c_str()); + cmd.push_back("-O3"); cmd.push_back("-o"); cmd.push_back(OutputFilename.c_str()); cmd.push_back(InputFilename.c_str()); diff --git a/tools/gccld/gccld.cpp b/tools/gccld/gccld.cpp index 0f5bc18a31f..389a6b13da4 100644 --- a/tools/gccld/gccld.cpp +++ b/tools/gccld/gccld.cpp @@ -78,6 +78,9 @@ namespace { cl::opt Native("native", cl::desc("Generate a native binary instead of a shell script")); + cl::opt + NativeCBE("native-cbe", + cl::desc("Generate a native binary with the C backend and GCC")); // Compatibility options that are ignored but supported by LD cl::opt @@ -276,6 +279,30 @@ int main(int argc, char **argv, char **envp) { // Remove the assembly language file. removeFile (AssemblyFile); + } else if (NativeCBE) { + std::string CFile = OutputFilename + ".cbe.c"; + + // Mark the output files for removal if we get an interrupt. + RemoveFileOnSignal(CFile); + RemoveFileOnSignal(OutputFilename); + + // Determine the locations of the llc and gcc programs. + std::string llc = FindExecutable("llc", argv[0]); + std::string gcc = FindExecutable("gcc", argv[0]); + if (llc.empty()) + return PrintAndReturn(argv[0], "Failed to find llc"); + if (gcc.empty()) + return PrintAndReturn(argv[0], "Failed to find gcc"); + + // Generate an assembly language file for the bytecode. + if (Verbose) std::cout << "Generating Assembly Code\n"; + GenerateCFile(CFile, RealBytecodeOutput, llc, envp); + if (Verbose) std::cout << "Generating Native Code\n"; + GenerateNative(OutputFilename, CFile, Libraries, LibPaths, gcc, envp); + + // Remove the assembly language file. + removeFile(CFile); + } else { // Output the script to start the program... std::ofstream Out2(OutputFilename.c_str()); diff --git a/tools/gccld/gccld.h b/tools/gccld/gccld.h index e5b865e3a4f..8913d379fb9 100644 --- a/tools/gccld/gccld.h +++ b/tools/gccld/gccld.h @@ -47,6 +47,9 @@ GenerateAssembly (const std::string & OutputFilename, const std::string & InputFilename, const std::string & llc, char ** const envp); + +int GenerateCFile(const std::string &OutputFile, const std::string &InputFile, + const std::string &llc, char ** const envp); int GenerateNative (const std::string & OutputFilename, const std::string & InputFilename,