added a skeleton of the ARM backend

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28301 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2006-05-14 22:18:28 +00:00
parent a3fdc02466
commit 7bc59bc395
16 changed files with 901 additions and 2 deletions

View File

@ -285,7 +285,7 @@ AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-target],
[Build specific host targets: all,host-only,{target-name} (default=all)]),,
enableval=all)
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM" ;;
host-only)
case "$llvm_cv_target_arch" in
x86) TARGETS_TO_BUILD="X86" ;;

2
configure vendored
View File

@ -3107,7 +3107,7 @@ else
enableval=all
fi;
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM" ;;
host-only)
case "$llvm_cv_target_arch" in
x86) TARGETS_TO_BUILD="X86" ;;

40
lib/Target/ARM/ARM.h Normal file
View File

@ -0,0 +1,40 @@
//===-- ARM.h - Top-level interface for ARM representation---- --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the entry points for global functions defined in the LLVM
// ARM back-end.
//
//===----------------------------------------------------------------------===//
#ifndef TARGET_ARM_H
#define TARGET_ARM_H
#include <iosfwd>
#include <cassert>
namespace llvm {
class FunctionPass;
class TargetMachine;
FunctionPass *createARMISelDag(TargetMachine &TM);
FunctionPass *createARMCodePrinterPass(std::ostream &OS, TargetMachine &TM);
} // end namespace llvm;
// Defines symbolic names for ARM registers. This defines a mapping from
// register name to register number.
//
#include "ARMGenRegisterNames.inc"
// Defines symbolic names for the ARM instructions.
//
#include "ARMGenInstrNames.inc"
#endif

51
lib/Target/ARM/ARM.td Normal file
View File

@ -0,0 +1,51 @@
//===- ARM.td - Describe the ARM Target Machine -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Target-independent interfaces which we are implementing
//===----------------------------------------------------------------------===//
include "../Target.td"
//===----------------------------------------------------------------------===//
// Register File Description
//===----------------------------------------------------------------------===//
include "ARMRegisterInfo.td"
//===----------------------------------------------------------------------===//
// Instruction Descriptions
//===----------------------------------------------------------------------===//
include "ARMInstrInfo.td"
def ARMInstrInfo : InstrInfo {
// Define how we want to layout our target-specific information field.
let TSFlagsFields = [];
let TSFlagsShifts = [];
}
//===----------------------------------------------------------------------===//
// Declare the target which we are implementing
//===----------------------------------------------------------------------===//
def ARM : Target {
// Pointers are 32-bits in size.
let PointerType = i32;
// FIXME: Specify callee-saved registers
let CalleeSavedRegisters = [];
// Pull in Instruction Info:
let InstructionSet = ARMInstrInfo;
}

View File

@ -0,0 +1,115 @@
//===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format ARM assembly language.
//
//===----------------------------------------------------------------------===//
#include "ARM.h"
#include "ARMInstrInfo.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
#include <iostream>
using namespace llvm;
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
struct ARMAsmPrinter : public AsmPrinter {
ARMAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) {
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";
Data64bitsDirective = 0;
ZeroDirective = "\t.skip\t";
CommentString = "!";
ConstantPoolSection = "\t.section \".rodata\",#alloc\n";
}
/// We name each basic block in a Function with a unique number, so
/// that we can consistently refer to them later. This is cleared
/// at the beginning of each call to runOnMachineFunction().
///
typedef std::map<const Value *, unsigned> ValueMapTy;
ValueMapTy NumberForBB;
virtual const char *getPassName() const {
return "ARM Assembly Printer";
}
void printOperand(const MachineInstr *MI, int opNum);
void printMemOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
void printCCOperand(const MachineInstr *MI, int opNum);
bool printInstruction(const MachineInstr *MI); // autogenerated.
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
};
} // end of anonymous namespace
#include "ARMGenAsmWriter.inc"
/// createARMCodePrinterPass - Returns a pass that prints the ARM
/// assembly code for a MachineFunction to the given output stream,
/// using the given target machine description. This should work
/// regardless of whether the function is in SSA form.
///
FunctionPass *llvm::createARMCodePrinterPass(std::ostream &o,
TargetMachine &tm) {
return new ARMAsmPrinter(o, tm);
}
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
assert(0 && "not implemented");
// We didn't modify anything.
return false;
}
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
assert(0 && "not implemented");
}
void ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
const char *Modifier) {
assert(0 && "not implemented");
}
void ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
assert(0 && "not implemented");
}
bool ARMAsmPrinter::doInitialization(Module &M) {
Mang = new Mangler(M);
return false; // success
}
bool ARMAsmPrinter::doFinalization(Module &M) {
assert(0 && "not implemented");
AsmPrinter::doFinalization(M);
return false; // success
}

View File

@ -0,0 +1,137 @@
//===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an instruction selector for the ARM target.
//
//===----------------------------------------------------------------------===//
#include "ARM.h"
#include "ARMTargetMachine.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Intrinsics.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/Debug.h"
#include <iostream>
#include <set>
using namespace llvm;
namespace ARMISD {
enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END,
RET_FLAG,
};
}
namespace {
class ARMTargetLowering : public TargetLowering {
public:
ARMTargetLowering(TargetMachine &TM);
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand>
LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
unsigned CC,
bool isTailCall, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG);
};
}
ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
: TargetLowering(TM) {
setOperationAction(ISD::RET, MVT::Other, Custom);
}
std::pair<SDOperand, SDOperand>
ARMTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
bool isVarArg, unsigned CC,
bool isTailCall, SDOperand Callee,
ArgListTy &Args, SelectionDAG &DAG) {
assert(0 && "Not implemented");
}
static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
SDOperand Copy;
switch(Op.getNumOperands()) {
default:
assert(0 && "Do not know how to return this many arguments!");
abort();
case 1:
return SDOperand(); // ret void is legal
case 2:
Copy = DAG.getCopyToReg(Op.getOperand(0), ARM::R0, Op.getOperand(1), SDOperand());
break;
}
return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
}
SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default:
assert(0 && "Should not custom lower this!");
case ISD::RET:
return LowerRET(Op, DAG);
}
}
//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
/// ARMDAGToDAGISel - ARM specific code to select ARM machine
/// instructions for SelectionDAG operations.
///
namespace {
class ARMDAGToDAGISel : public SelectionDAGISel {
ARMTargetLowering Lowering;
public:
ARMDAGToDAGISel(TargetMachine &TM)
: SelectionDAGISel(Lowering), Lowering(TM) {
}
void Select(SDOperand &Result, SDOperand Op);
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
// Include the pieces autogenerated from the target description.
#include "ARMGenDAGISel.inc"
};
void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
DEBUG(BB->dump());
DAG.setRoot(SelectRoot(DAG.getRoot()));
CodeGenMap.clear();
DAG.RemoveDeadNodes();
ScheduleAndEmitDAG(DAG);
}
void ARMDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
SelectCode(Result, Op);
}
} // end anonymous namespace
/// createARMISelDag - This pass converts a legalized DAG into a
/// ARM-specific DAG, ready for instruction scheduling.
///
FunctionPass *llvm::createARMISelDag(TargetMachine &TM) {
return new ARMDAGToDAGISel(TM);
}

View File

@ -0,0 +1,58 @@
//===- ARMInstrInfo.cpp - ARM Instruction Information -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the ARM implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#include "ARMInstrInfo.h"
#include "ARM.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "ARMGenInstrInfo.inc"
using namespace llvm;
ARMInstrInfo::ARMInstrInfo()
: TargetInstrInfo(ARMInsts, sizeof(ARMInsts)/sizeof(ARMInsts[0])) {
}
/// Return true if the instruction is a register to register move and
/// leave the source and dest operands in the passed parameters.
///
bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
unsigned &SrcReg, unsigned &DstReg) const {
// We look for 3 kinds of patterns here:
// or with G0 or 0
// add with G0 or 0
// fmovs or FpMOVD (pseudo double move).
assert(0 && "not implemented");
return false;
}
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
/// the destination along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than loading from the stack slot.
unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI,
int &FrameIndex) const {
assert(0 && "not implemented");
return 0;
}
/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
/// the source reg along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than storing to the stack slot.
unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI,
int &FrameIndex) const {
assert(0 && "not implemented");
return 0;
}

View File

@ -0,0 +1,57 @@
//===- ARMInstrInfo.h - ARM Instruction Information --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the ARM implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef ARMINSTRUCTIONINFO_H
#define ARMINSTRUCTIONINFO_H
#include "llvm/Target/TargetInstrInfo.h"
#include "ARMRegisterInfo.h"
namespace llvm {
class ARMInstrInfo : public TargetInstrInfo {
const ARMRegisterInfo RI;
public:
ARMInstrInfo();
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
/// such, whenever a client has an instance of instruction info, it should
/// always be able to get register info as well (through this method).
///
virtual const MRegisterInfo &getRegisterInfo() const { return RI; }
/// Return true if the instruction is a register to register move and
/// leave the source and dest operands in the passed parameters.
///
virtual bool isMoveInstr(const MachineInstr &MI,
unsigned &SrcReg, unsigned &DstReg) const;
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
/// the destination along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than loading from the stack slot.
virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
/// the source reg along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than storing to the stack slot.
virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
};
}
#endif

View File

@ -0,0 +1,54 @@
//===- ARMInstrInfo.td - Target Description for ARM Target ----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the ARM instructions in TableGen format.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
class InstARM<dag ops, string asmstr, list<dag> pattern> : Instruction {
let Namespace = "ARM";
dag OperandList = ops;
let AsmString = asmstr;
let Pattern = pattern;
}
def SDT_ARMCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeq, [SDNPHasChain]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeq, [SDNPHasChain]>;
def SDT_ARMRetFlag : SDTypeProfile<0, 0, []>;
def retflag : SDNode<"ARMISD::RET_FLAG", SDT_ARMRetFlag,
[SDNPHasChain, SDNPOptInFlag]>;
def ADJCALLSTACKUP : InstARM<(ops i32imm:$amt),
"!ADJCALLSTACKUP $amt",
[(callseq_end imm:$amt)]>;
def ADJCALLSTACKDOWN : InstARM<(ops i32imm:$amt),
"!ADJCALLSTACKDOWN $amt",
[(callseq_start imm:$amt)]>;
def ldr : InstARM<(ops IntRegs:$dst, IntRegs:$addr),
"ldr $dst, [$addr]",
[(set IntRegs:$dst, (load IntRegs:$addr))]>;
def str : InstARM<(ops IntRegs:$src, IntRegs:$addr),
"str $src, [$addr]",
[(store IntRegs:$src, IntRegs:$addr)]>;
def mov : InstARM<(ops IntRegs:$dst, IntRegs:$b),
"mov $dst, $b", []>;

View File

@ -0,0 +1,91 @@
//===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the ARM implementation of the MRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#include "ARM.h"
#include "ARMRegisterInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Type.h"
#include "llvm/ADT/STLExtras.h"
#include <iostream>
using namespace llvm;
ARMRegisterInfo::ARMRegisterInfo()
: ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP) {
}
void ARMRegisterInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, int FI,
const TargetRegisterClass *RC) const {
// On the order of operands here: think "[FI + 0] = SrcReg".
assert (RC == ARM::IntRegsRegisterClass);
BuildMI(MBB, I, ARM::str, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
}
void ARMRegisterInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const {
assert (RC == ARM::IntRegsRegisterClass);
BuildMI(MBB, I, ARM::ldr, 2, DestReg).addFrameIndex(FI).addImm(0);
}
void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const {
assert (RC == ARM::IntRegsRegisterClass);
BuildMI(MBB, I, ARM::mov, 1, DestReg).addReg(SrcReg);
}
MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
unsigned OpNum,
int FI) const {
return NULL;
}
void ARMRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MBB.erase(I);
}
void
ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
assert(0 && "Not Implemented");
}
void ARMRegisterInfo::
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
}
void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
}
unsigned ARMRegisterInfo::getRARegister() const {
return ARM::R14;
}
unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
return ARM::R13;
}
#include "ARMGenRegisterInfo.inc"

View File

@ -0,0 +1,66 @@
//===- ARMRegisterInfo.h - ARM Register Information Impl --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the ARM implementation of the MRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef ARMREGISTERINFO_H
#define ARMREGISTERINFO_H
#include "llvm/Target/MRegisterInfo.h"
#include "ARMGenRegisterInfo.h.inc"
namespace llvm {
class Type;
struct ARMRegisterInfo : public ARMGenRegisterInfo {
ARMRegisterInfo();
/// Code Generation virtual methods...
void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned SrcReg, int FrameIndex,
const TargetRegisterClass *RC) const;
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC) const;
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const;
virtual MachineInstr* foldMemoryOperand(MachineInstr* MI,
unsigned OpNum,
int FrameIndex) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const;
};
} // end namespace llvm
#endif

View File

@ -0,0 +1,56 @@
//===- ARMRegisterInfo.td - ARM Register defs ----------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Declarations that describe the ARM register file
//===----------------------------------------------------------------------===//
// Registers are identified with 4-bit ID numbers.
class ARMReg<bits<4> num, string n> : Register<n> {
field bits<4> Num;
let Namespace = "ARM";
}
// Integer registers
def R0 : ARMReg< 0, "R0">, DwarfRegNum<0>;
def R1 : ARMReg< 1, "R1">, DwarfRegNum<1>;
def R2 : ARMReg< 2, "R2">, DwarfRegNum<2>;
def R3 : ARMReg< 3, "R3">, DwarfRegNum<3>;
def R4 : ARMReg< 4, "R4">, DwarfRegNum<4>;
def R5 : ARMReg< 5, "R5">, DwarfRegNum<5>;
def R6 : ARMReg< 6, "R6">, DwarfRegNum<6>;
def R7 : ARMReg< 7, "R7">, DwarfRegNum<7>;
def R8 : ARMReg< 8, "R8">, DwarfRegNum<8>;
def R9 : ARMReg< 9, "R9">, DwarfRegNum<9>;
def R10 : ARMReg<10, "R10">, DwarfRegNum<10>;
def R11 : ARMReg<11, "R11">, DwarfRegNum<11>;
def R12 : ARMReg<12, "R12">, DwarfRegNum<12>;
def R13 : ARMReg<13, "R13">, DwarfRegNum<13>;
def R14 : ARMReg<14, "R14">, DwarfRegNum<14>;
def R15 : ARMReg<15, "R15">, DwarfRegNum<15>;
// Register classes.
//
// FIXME: the register order should be defined in terms of the preferred
// allocation order...
//
def IntRegs : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
R7, R8, R9, R10, R11, R12,
R13, R14, R15]> {
let MethodProtos = [{
iterator allocation_order_end(MachineFunction &MF) const;
}];
let MethodBodies = [{
IntRegsClass::iterator
IntRegsClass::allocation_order_end(MachineFunction &MF) const {
return end() - 1;
}
}];
}

View File

@ -0,0 +1,99 @@
//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
#include "ARMTargetMachine.h"
#include "ARM.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include <iostream>
using namespace llvm;
namespace {
// Register the target.
RegisterTarget<ARMTargetMachine> X("arm", " ARM");
}
/// TargetMachine ctor - Create an ILP32 architecture model
///
ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
: TargetMachine("ARM"),
DataLayout("ARM", false, 4, 4),
InstrInfo(),
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
}
unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
std::string TT = M.getTargetTriple();
if (TT.size() >= 4 && std::string(TT.begin(), TT.begin()+4) == "arm-")
return 20;
if (M.getPointerSize() == Module::Pointer32)
return 1;
else
return 0;
}
/// addPassesToEmitFile - Add passes to the specified pass manager
/// to implement a static compiler for this target.
///
bool ARMTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
CodeGenFileType FileType,
bool Fast) {
if (FileType != TargetMachine::AssemblyFile)
return true;
// Run loop strength reduction before anything else.
if (!Fast)
PM.add(createLoopStrengthReducePass());
// FIXME: Implement efficient support for garbage collection intrinsics.
PM.add(createLowerGCPass());
// FIXME: implement the invoke/unwind instructions!
PM.add(createLowerInvokePass());
// Print LLVM code input to instruction selector:
if (PrintMachineCode)
PM.add(new PrintFunctionPass());
// Make sure that no unreachable blocks are instruction selected.
PM.add(createUnreachableBlockEliminationPass());
PM.add(createARMISelDag(*this));
// Print machine instructions as they were initially generated.
if (PrintMachineCode)
PM.add(createMachineFunctionPrinterPass(&std::cerr));
PM.add(createRegisterAllocator());
PM.add(createPrologEpilogCodeInserter());
// Print machine instructions after register allocation and prolog/epilog
// insertion.
if (PrintMachineCode)
PM.add(createMachineFunctionPrinterPass(&std::cerr));
// Output assembly language.
PM.add(createARMCodePrinterPass(Out, *this));
// Delete the MachineInstrs we generated, since they're no longer needed.
PM.add(createMachineCodeDeleter());
return false;
}

View File

@ -0,0 +1,49 @@
//===-- ARMTargetMachine.h - Define TargetMachine for ARM -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the ARM specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
#ifndef ARMTARGETMACHINE_H
#define ARMTARGETMACHINE_H
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/PassManager.h"
#include "ARMInstrInfo.h"
namespace llvm {
class Module;
class ARMTargetMachine : public TargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
ARMInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
public:
ARMTargetMachine(const Module &M, const std::string &FS);
virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; }
virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; }
virtual const MRegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
static unsigned getModuleMatchQuality(const Module &M);
virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
CodeGenFileType FileType, bool Fast);
};
} // end namespace llvm
#endif

21
lib/Target/ARM/Makefile Normal file
View File

@ -0,0 +1,21 @@
##===- lib/Target/ARM/Makefile -----------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file was developed by the "Instituto Nokia de Tecnologia" and
# is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../..
LIBRARYNAME = LLVMARM
TARGET = ARM
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
ARMGenRegisterInfo.inc ARMGenInstrNames.inc \
ARMGenInstrInfo.inc ARMGenAsmWriter.inc \
ARMGenDAGISel.inc
include $(LEVEL)/Makefile.common

View File

@ -48,6 +48,11 @@ ifneq ($(strip $(filter IA64,$(TARGETS_TO_BUILD))),)
USEDLIBS += LLVMIA64
endif
#Check for ARM Target
ifneq ($(strip $(filter ARM,$(TARGETS_TO_BUILD))),)
USEDLIBS += LLVMARM
endif
USEDLIBS += \
LLVMSelectionDAG \
LLVMCodeGen \