#include <memory>
#include <fstream>
+using namespace llvm;
+
// General options for llc. Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
-enum ArchName { noarch, x86, Sparc };
+enum ArchName { noarch, X86, Sparc, PowerPC, CBackend };
static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
- cl::values(clEnumVal(x86, " IA-32 (Pentium and above)"),
- clEnumValN(Sparc, "sparc", " SPARC V9"),
+ cl::values(clEnumValN(X86, "x86", " IA-32 (Pentium and above)"),
+ clEnumValN(Sparc, "sparc", " SPARC V9"),
+ clEnumValN(PowerPC, "powerpc", " PowerPC"),
+ clEnumValN(CBackend, "c", " C backend"),
0),
cl::init(noarch));
// Allocate target machine. First, check whether the user has
// explicitly specified an architecture to compile for.
- TargetMachine* (*TargetMachineAllocator)(const Module&) = 0;
+ TargetMachine* (*TargetMachineAllocator)(const Module&,
+ IntrinsicLowering *) = 0;
switch (Arch) {
- case x86:
+ case CBackend:
+ TargetMachineAllocator = allocateCTargetMachine;
+ break;
+ case X86:
TargetMachineAllocator = allocateX86TargetMachine;
break;
case Sparc:
TargetMachineAllocator = allocateSparcTargetMachine;
break;
+ case PowerPC:
+ TargetMachineAllocator = allocatePowerPCTargetMachine;
+ break;
default:
// Decide what the default target machine should be, by looking at
// the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
if (mod.getEndianness() == Module::LittleEndian &&
mod.getPointerSize() == Module::Pointer32) {
TargetMachineAllocator = allocateX86TargetMachine;
+ } else if (mod.getEndianness() == Module::BigEndian &&
+ mod.getPointerSize() == Module::Pointer32) {
+ TargetMachineAllocator = allocatePowerPCTargetMachine;
} else if (mod.getEndianness() == Module::BigEndian &&
mod.getPointerSize() == Module::Pointer64) {
TargetMachineAllocator = allocateSparcTargetMachine;
TargetMachineAllocator = allocateX86TargetMachine;
#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
TargetMachineAllocator = allocateSparcTargetMachine;
+#elif defined(__POWERPC__) || defined(__ppc__) || defined(__APPLE__)
+ TargetMachineAllocator = allocatePowerPCTargetMachine;
#else
std::cerr << argv[0] << ": module does not specify a target to use. "
- << "You must use the -march option.\n";
+ << "You must use the -march option. If no native target is "
+ << "available, use -march=c to emit C code.\n";
return 1;
#endif
}
break;
}
- std::auto_ptr<TargetMachine> target(TargetMachineAllocator(mod));
+ std::auto_ptr<TargetMachine> target(TargetMachineAllocator(mod, 0));
assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get();
const TargetData &TD = Target.getTargetData();
Out = &std::cout;
} else {
OutputFilename = GetFileNameRoot(InputFilename);
- OutputFilename += ".s";
+
+ if (Arch != CBackend)
+ OutputFilename += ".s";
+ else
+ OutputFilename += ".cbe.c";
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!