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