SparcTargetMachine.cpp revision bc641b9d8b5ecafe0137c1a49f4777608981d81b
12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===-- SparcTargetMachine.cpp - Define TargetMachine for Sparc -----------===// 22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The LLVM Compiler Infrastructure 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file was developed by the LLVM research group and is distributed under 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// the University of Illinois Open Source License. See LICENSE.TXT for details. 72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "SparcTargetMachine.h" 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "Sparc.h" 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/Assembly/PrintModulePass.h" 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/Module.h" 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/PassManager.h" 182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/CodeGen/MachineFunction.h" 195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "llvm/CodeGen/Passes.h" 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/Target/TargetOptions.h" 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/Target/TargetMachineRegistry.h" 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/Transforms/Scalar.h" 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <iostream> 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesusing namespace llvm; 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace { 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Register the target. 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines RegisterTarget<SparcTargetMachine> X("sparc", " SPARC"); 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/// SparcTargetMachine ctor - Create an ILP32 architecture model 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/// 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesSparcTargetMachine::SparcTargetMachine(const Module &M, const std::string &FS) 342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines : TargetMachine("Sparc", false, 4, 4), 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Subtarget(M, FS), InstrInfo(Subtarget), 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) { 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesunsigned SparcTargetMachine::getModuleMatchQuality(const Module &M) { 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines std::string TT = M.getTargetTriple(); 412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (TT.size() >= 6 && std::string(TT.begin(), TT.begin()+6) == "sparc-") 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 20; 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (M.getEndianness() == Module::BigEndian && 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines M.getPointerSize() == Module::Pointer32) 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifdef __sparc__ 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 20; // BE/32 ==> Prefer sparc on sparc 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 5; // BE/32 ==> Prefer ppc elsewhere 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (M.getEndianness() != Module::AnyEndianness || 522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines M.getPointerSize() != Module::AnyPointerSize) 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; // Match for some other target 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/// addPassesToEmitFile - Add passes to the specified pass manager 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/// to implement a static compiler for this target. 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/// 612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesbool SparcTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, 622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines CodeGenFileType FileType, 632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines bool Fast) { 642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (FileType != TargetMachine::AssemblyFile) return true; 652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Run loop strength reduction before anything else. 672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!Fast) PM.add(createLoopStrengthReducePass()); 682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // FIXME: Implement efficient support for garbage collection intrinsics. 702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createLowerGCPass()); 712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // FIXME: implement the invoke/unwind instructions! 732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createLowerInvokePass()); 742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // FIXME: implement the switch instruction in the instruction selector. 762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createLowerSwitchPass()); 772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Print LLVM code input to instruction selector: 792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (PrintMachineCode) 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(new PrintFunctionPass()); 812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Make sure that no unreachable blocks are instruction selected. 832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createUnreachableBlockEliminationPass()); 842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createSparcISelDag(*this)); 862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Print machine instructions as they were initially generated. 882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (PrintMachineCode) 892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createMachineFunctionPrinterPass(&std::cerr)); 902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createRegisterAllocator()); 922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createPrologEpilogCodeInserter()); 932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Print machine instructions after register allocation and prolog/epilog 952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // insertion. 962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (PrintMachineCode) 972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createMachineFunctionPrinterPass(&std::cerr)); 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createSparcFPMoverPass(*this)); 1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createSparcDelaySlotFillerPass(*this)); 1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Print machine instructions after filling delay slots. 1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (PrintMachineCode) 1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createMachineFunctionPrinterPass(&std::cerr)); 1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Output assembly language. 1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createSparcCodePrinterPass(Out, *this)); 1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Delete the MachineInstrs we generated, since they're no longer needed. 1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PM.add(createMachineCodeDeleter()); 1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return false; 1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines