1 //===-- M68kTargetMachine.cpp - M68k Target Machine -------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file contains implementation for M68k target machine. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "M68kTargetMachine.h" 15 #include "M68k.h" 16 #include "M68kSubtarget.h" 17 #include "M68kTargetObjectFile.h" 18 #include "TargetInfo/M68kTargetInfo.h" 19 #include "llvm/CodeGen/GlobalISel/IRTranslator.h" 20 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 21 #include "llvm/CodeGen/GlobalISel/Legalizer.h" 22 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" 23 #include "llvm/CodeGen/Passes.h" 24 #include "llvm/CodeGen/TargetPassConfig.h" 25 #include "llvm/IR/LegacyPassManager.h" 26 #include "llvm/InitializePasses.h" 27 #include "llvm/MC/TargetRegistry.h" 28 #include "llvm/PassRegistry.h" 29 #include <memory> 30 31 using namespace llvm; 32 33 #define DEBUG_TYPE "m68k" 34 35 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() { 36 RegisterTargetMachine<M68kTargetMachine> X(getTheM68kTarget()); 37 auto *PR = PassRegistry::getPassRegistry(); 38 initializeGlobalISel(*PR); 39 } 40 41 namespace { 42 43 std::string computeDataLayout(const Triple &TT, StringRef CPU, 44 const TargetOptions &Options) { 45 std::string Ret = ""; 46 // M68k is Big Endian 47 Ret += "E"; 48 49 // FIXME how to wire it with the used object format? 50 Ret += "-m:e"; 51 52 // M68k pointers are always 32 bit wide even for 16-bit CPUs. 53 // The ABI only specifies 16-bit alignment. 54 // On at least the 68020+ with a 32-bit bus, there is a performance benefit 55 // to having 32-bit alignment. 56 Ret += "-p:32:16:32"; 57 58 // Bytes do not require special alignment, words are word aligned and 59 // long words are word aligned at minimum. 60 Ret += "-i8:8:8-i16:16:16-i32:16:32"; 61 62 // FIXME no floats at the moment 63 64 // The registers can hold 8, 16, 32 bits 65 Ret += "-n8:16:32"; 66 67 Ret += "-a:0:16-S16"; 68 69 return Ret; 70 } 71 72 Reloc::Model getEffectiveRelocModel(const Triple &TT, 73 Optional<Reloc::Model> RM) { 74 // If not defined we default to static 75 if (!RM.hasValue()) { 76 return Reloc::Static; 77 } 78 79 return *RM; 80 } 81 82 CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM, 83 bool JIT) { 84 if (!CM) { 85 return CodeModel::Small; 86 } else if (CM == CodeModel::Large) { 87 llvm_unreachable("Large code model is not supported"); 88 } else if (CM == CodeModel::Kernel) { 89 llvm_unreachable("Kernel code model is not implemented yet"); 90 } 91 return CM.getValue(); 92 } 93 } // end anonymous namespace 94 95 M68kTargetMachine::M68kTargetMachine(const Target &T, const Triple &TT, 96 StringRef CPU, StringRef FS, 97 const TargetOptions &Options, 98 Optional<Reloc::Model> RM, 99 Optional<CodeModel::Model> CM, 100 CodeGenOpt::Level OL, bool JIT) 101 : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT, CPU, FS, 102 Options, getEffectiveRelocModel(TT, RM), 103 ::getEffectiveCodeModel(CM, JIT), OL), 104 TLOF(std::make_unique<M68kELFTargetObjectFile>()), 105 Subtarget(TT, CPU, FS, *this) { 106 initAsmInfo(); 107 } 108 109 M68kTargetMachine::~M68kTargetMachine() {} 110 111 const M68kSubtarget * 112 M68kTargetMachine::getSubtargetImpl(const Function &F) const { 113 Attribute CPUAttr = F.getFnAttribute("target-cpu"); 114 Attribute FSAttr = F.getFnAttribute("target-features"); 115 116 auto CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 117 auto FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 118 119 auto &I = SubtargetMap[CPU + FS]; 120 if (!I) { 121 // This needs to be done before we create a new subtarget since any 122 // creation will depend on the TM and the code generation flags on the 123 // function that reside in TargetOptions. 124 resetTargetOptions(F); 125 I = std::make_unique<M68kSubtarget>(TargetTriple, CPU, FS, *this); 126 } 127 return I.get(); 128 } 129 130 //===----------------------------------------------------------------------===// 131 // Pass Pipeline Configuration 132 //===----------------------------------------------------------------------===// 133 134 namespace { 135 class M68kPassConfig : public TargetPassConfig { 136 public: 137 M68kPassConfig(M68kTargetMachine &TM, PassManagerBase &PM) 138 : TargetPassConfig(TM, PM) {} 139 140 M68kTargetMachine &getM68kTargetMachine() const { 141 return getTM<M68kTargetMachine>(); 142 } 143 144 const M68kSubtarget &getM68kSubtarget() const { 145 return *getM68kTargetMachine().getSubtargetImpl(); 146 } 147 bool addIRTranslator() override; 148 bool addLegalizeMachineIR() override; 149 bool addRegBankSelect() override; 150 bool addGlobalInstructionSelect() override; 151 bool addInstSelector() override; 152 void addPreSched2() override; 153 void addPreEmitPass() override; 154 }; 155 } // namespace 156 157 TargetPassConfig *M68kTargetMachine::createPassConfig(PassManagerBase &PM) { 158 return new M68kPassConfig(*this, PM); 159 } 160 161 bool M68kPassConfig::addInstSelector() { 162 // Install an instruction selector. 163 addPass(createM68kISelDag(getM68kTargetMachine())); 164 addPass(createM68kGlobalBaseRegPass()); 165 return false; 166 } 167 168 bool M68kPassConfig::addIRTranslator() { 169 addPass(new IRTranslator()); 170 return false; 171 } 172 173 bool M68kPassConfig::addLegalizeMachineIR() { 174 addPass(new Legalizer()); 175 return false; 176 } 177 178 bool M68kPassConfig::addRegBankSelect() { 179 addPass(new RegBankSelect()); 180 return false; 181 } 182 183 bool M68kPassConfig::addGlobalInstructionSelect() { 184 addPass(new InstructionSelect()); 185 return false; 186 } 187 188 void M68kPassConfig::addPreSched2() { addPass(createM68kExpandPseudoPass()); } 189 190 void M68kPassConfig::addPreEmitPass() { 191 addPass(createM68kCollapseMOVEMPass()); 192 } 193