mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-04 22:07:27 +00:00
b9803a8fa6
load of a GV from constantpool and then add pc. It allows the code sequence to be rematerializable so it would be hoisted by machine licm. - Add a late pass to break these pseudo instructions into a number of real instructions. Also move the code in Thumb2 IT pass that breaks up t2MOVi32imm to this pass. This is done before post regalloc scheduling to allow the scheduler to proper schedule these instructions. It also allow them to be if-converted and shrunk by later passes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86304 91177308-0d34-0410-b5e6-96231b3b80d8
194 lines
6.7 KiB
C++
194 lines
6.7 KiB
C++
//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ARMTargetMachine.h"
|
|
#include "ARMMCAsmInfo.h"
|
|
#include "ARMFrameInfo.h"
|
|
#include "ARM.h"
|
|
#include "llvm/PassManager.h"
|
|
#include "llvm/CodeGen/Passes.h"
|
|
#include "llvm/Support/FormattedStream.h"
|
|
#include "llvm/Target/TargetOptions.h"
|
|
#include "llvm/Target/TargetRegistry.h"
|
|
using namespace llvm;
|
|
|
|
static const MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
|
|
Triple TheTriple(TT);
|
|
switch (TheTriple.getOS()) {
|
|
case Triple::Darwin:
|
|
return new ARMMCAsmInfoDarwin();
|
|
default:
|
|
return new ARMELFMCAsmInfo();
|
|
}
|
|
}
|
|
|
|
|
|
extern "C" void LLVMInitializeARMTarget() {
|
|
// Register the target.
|
|
RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
|
|
RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
|
|
|
|
// Register the target asm info.
|
|
RegisterAsmInfoFn A(TheARMTarget, createMCAsmInfo);
|
|
RegisterAsmInfoFn B(TheThumbTarget, createMCAsmInfo);
|
|
}
|
|
|
|
/// TargetMachine ctor - Create an ARM architecture model.
|
|
///
|
|
ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
|
|
const std::string &TT,
|
|
const std::string &FS,
|
|
bool isThumb)
|
|
: LLVMTargetMachine(T, TT),
|
|
Subtarget(TT, FS, isThumb),
|
|
FrameInfo(Subtarget),
|
|
JITInfo(),
|
|
InstrItins(Subtarget.getInstrItineraryData()) {
|
|
DefRelocModel = getRelocationModel();
|
|
}
|
|
|
|
ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
|
|
const std::string &FS)
|
|
: ARMBaseTargetMachine(T, TT, FS, false), InstrInfo(Subtarget),
|
|
DataLayout(Subtarget.isAPCS_ABI() ?
|
|
std::string("e-p:32:32-f64:32:32-i64:32:32") :
|
|
std::string("e-p:32:32-f64:64:64-i64:64:64")),
|
|
TLInfo(*this) {
|
|
}
|
|
|
|
ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
|
|
const std::string &FS)
|
|
: ARMBaseTargetMachine(T, TT, FS, true),
|
|
InstrInfo(Subtarget.hasThumb2()
|
|
? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
|
|
: ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
|
|
DataLayout(Subtarget.isAPCS_ABI() ?
|
|
std::string("e-p:32:32-f64:32:32-i64:32:32-"
|
|
"i16:16:32-i8:8:32-i1:8:32-a:0:32") :
|
|
std::string("e-p:32:32-f64:64:64-i64:64:64-"
|
|
"i16:16:32-i8:8:32-i1:8:32-a:0:32")),
|
|
TLInfo(*this) {
|
|
}
|
|
|
|
|
|
|
|
// Pass Pipeline Configuration
|
|
bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel) {
|
|
PM.add(createARMISelDag(*this, OptLevel));
|
|
return false;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel) {
|
|
if (Subtarget.hasNEON())
|
|
PM.add(createNEONPreAllocPass());
|
|
|
|
// FIXME: temporarily disabling load / store optimization pass for Thumb1.
|
|
if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
|
|
PM.add(createARMLoadStoreOptimizationPass(true));
|
|
return true;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel) {
|
|
// FIXME: temporarily disabling load / store optimization pass for Thumb1.
|
|
if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
|
|
PM.add(createARMLoadStoreOptimizationPass());
|
|
|
|
// Expand some pseudo instructions into multiple instructions to allow
|
|
// proper scheduling.
|
|
PM.add(createARMExpandPseudoPass());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel) {
|
|
// FIXME: temporarily disabling load / store optimization pass for Thumb1.
|
|
if (OptLevel != CodeGenOpt::None) {
|
|
if (!Subtarget.isThumb1Only())
|
|
PM.add(createIfConverterPass());
|
|
if (Subtarget.hasNEON())
|
|
PM.add(createNEONMoveFixPass());
|
|
}
|
|
|
|
if (Subtarget.isThumb2()) {
|
|
PM.add(createThumb2ITBlockPass());
|
|
PM.add(createThumb2SizeReductionPass());
|
|
}
|
|
|
|
PM.add(createARMConstantIslandPass());
|
|
return true;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel,
|
|
MachineCodeEmitter &MCE) {
|
|
// FIXME: Move this to TargetJITInfo!
|
|
if (DefRelocModel == Reloc::Default)
|
|
setRelocationModel(Reloc::Static);
|
|
|
|
// Machine code emitter pass for ARM.
|
|
PM.add(createARMCodeEmitterPass(*this, MCE));
|
|
return false;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel,
|
|
JITCodeEmitter &JCE) {
|
|
// FIXME: Move this to TargetJITInfo!
|
|
if (DefRelocModel == Reloc::Default)
|
|
setRelocationModel(Reloc::Static);
|
|
|
|
// Machine code emitter pass for ARM.
|
|
PM.add(createARMJITCodeEmitterPass(*this, JCE));
|
|
return false;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel,
|
|
ObjectCodeEmitter &OCE) {
|
|
// FIXME: Move this to TargetJITInfo!
|
|
if (DefRelocModel == Reloc::Default)
|
|
setRelocationModel(Reloc::Static);
|
|
|
|
// Machine code emitter pass for ARM.
|
|
PM.add(createARMObjectCodeEmitterPass(*this, OCE));
|
|
return false;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel,
|
|
MachineCodeEmitter &MCE) {
|
|
// Machine code emitter pass for ARM.
|
|
PM.add(createARMCodeEmitterPass(*this, MCE));
|
|
return false;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel,
|
|
JITCodeEmitter &JCE) {
|
|
// Machine code emitter pass for ARM.
|
|
PM.add(createARMJITCodeEmitterPass(*this, JCE));
|
|
return false;
|
|
}
|
|
|
|
bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
|
CodeGenOpt::Level OptLevel,
|
|
ObjectCodeEmitter &OCE) {
|
|
// Machine code emitter pass for ARM.
|
|
PM.add(createARMObjectCodeEmitterPass(*this, OCE));
|
|
return false;
|
|
}
|
|
|