125 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- AVRTargetMachine.cpp - Define TargetMachine for AVR ---------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// This file defines the AVR specific subclass of TargetMachine.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "AVRTargetMachine.h"
 | 
						|
 | 
						|
#include "llvm/CodeGen/Passes.h"
 | 
						|
#include "llvm/CodeGen/TargetPassConfig.h"
 | 
						|
#include "llvm/IR/LegacyPassManager.h"
 | 
						|
#include "llvm/IR/Module.h"
 | 
						|
#include "llvm/Support/TargetRegistry.h"
 | 
						|
 | 
						|
#include "AVR.h"
 | 
						|
#include "AVRTargetObjectFile.h"
 | 
						|
#include "MCTargetDesc/AVRMCTargetDesc.h"
 | 
						|
#include "TargetInfo/AVRTargetInfo.h"
 | 
						|
 | 
						|
namespace llvm {
 | 
						|
 | 
						|
static const char *AVRDataLayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8";
 | 
						|
 | 
						|
/// Processes a CPU name.
 | 
						|
static StringRef getCPU(StringRef CPU) {
 | 
						|
  if (CPU.empty() || CPU == "generic") {
 | 
						|
    return "avr2";
 | 
						|
  }
 | 
						|
 | 
						|
  return CPU;
 | 
						|
}
 | 
						|
 | 
						|
static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
 | 
						|
  return RM.hasValue() ? *RM : Reloc::Static;
 | 
						|
}
 | 
						|
 | 
						|
AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT,
 | 
						|
                                   StringRef CPU, StringRef FS,
 | 
						|
                                   const TargetOptions &Options,
 | 
						|
                                   Optional<Reloc::Model> RM,
 | 
						|
                                   Optional<CodeModel::Model> CM,
 | 
						|
                                   CodeGenOpt::Level OL, bool JIT)
 | 
						|
    : LLVMTargetMachine(T, AVRDataLayout, TT, getCPU(CPU), FS, Options,
 | 
						|
                        getEffectiveRelocModel(RM),
 | 
						|
                        getEffectiveCodeModel(CM, CodeModel::Small), OL),
 | 
						|
      SubTarget(TT, getCPU(CPU), FS, *this) {
 | 
						|
  this->TLOF = make_unique<AVRTargetObjectFile>();
 | 
						|
  initAsmInfo();
 | 
						|
}
 | 
						|
 | 
						|
namespace {
 | 
						|
/// AVR Code Generator Pass Configuration Options.
 | 
						|
class AVRPassConfig : public TargetPassConfig {
 | 
						|
public:
 | 
						|
  AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM)
 | 
						|
      : TargetPassConfig(TM, PM) {}
 | 
						|
 | 
						|
  AVRTargetMachine &getAVRTargetMachine() const {
 | 
						|
    return getTM<AVRTargetMachine>();
 | 
						|
  }
 | 
						|
 | 
						|
  bool addInstSelector() override;
 | 
						|
  void addPreSched2() override;
 | 
						|
  void addPreEmitPass() override;
 | 
						|
  void addPreRegAlloc() override;
 | 
						|
};
 | 
						|
} // namespace
 | 
						|
 | 
						|
TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) {
 | 
						|
  return new AVRPassConfig(*this, PM);
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void LLVMInitializeAVRTarget() {
 | 
						|
  // Register the target.
 | 
						|
  RegisterTargetMachine<AVRTargetMachine> X(getTheAVRTarget());
 | 
						|
 | 
						|
  auto &PR = *PassRegistry::getPassRegistry();
 | 
						|
  initializeAVRExpandPseudoPass(PR);
 | 
						|
  initializeAVRRelaxMemPass(PR);
 | 
						|
}
 | 
						|
 | 
						|
const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const {
 | 
						|
  return &SubTarget;
 | 
						|
}
 | 
						|
 | 
						|
const AVRSubtarget *AVRTargetMachine::getSubtargetImpl(const Function &) const {
 | 
						|
  return &SubTarget;
 | 
						|
}
 | 
						|
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
// Pass Pipeline Configuration
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
bool AVRPassConfig::addInstSelector() {
 | 
						|
  // Install an instruction selector.
 | 
						|
  addPass(createAVRISelDag(getAVRTargetMachine(), getOptLevel()));
 | 
						|
  // Create the frame analyzer pass used by the PEI pass.
 | 
						|
  addPass(createAVRFrameAnalyzerPass());
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
void AVRPassConfig::addPreRegAlloc() {
 | 
						|
  // Create the dynalloc SP save/restore pass to handle variable sized allocas.
 | 
						|
  addPass(createAVRDynAllocaSRPass());
 | 
						|
}
 | 
						|
 | 
						|
void AVRPassConfig::addPreSched2() {
 | 
						|
  addPass(createAVRRelaxMemPass());
 | 
						|
  addPass(createAVRExpandPseudoPass());
 | 
						|
}
 | 
						|
 | 
						|
void AVRPassConfig::addPreEmitPass() {
 | 
						|
  // Must run branch selection immediately preceding the asm printer.
 | 
						|
  addPass(&BranchRelaxationPassID);
 | 
						|
}
 | 
						|
 | 
						|
} // end of namespace llvm
 |