added a skeleton of the ARM backend
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28301 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 3917db0..b29ce31 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -285,7 +285,7 @@
[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" ;;
diff --git a/configure b/configure
index 351cdd5..b235fcd 100755
--- a/configure
+++ b/configure
@@ -3107,7 +3107,7 @@
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" ;;
diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h
new file mode 100644
index 0000000..167d71e
--- /dev/null
+++ b/lib/Target/ARM/ARM.h
@@ -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
diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td
new file mode 100644
index 0000000..a7b7e6e
--- /dev/null
+++ b/lib/Target/ARM/ARM.td
@@ -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;
+}
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
new file mode 100644
index 0000000..612540d
--- /dev/null
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -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
+}
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
new file mode 100644
index 0000000..f7611b6
--- /dev/null
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -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);
+}
diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp
new file mode 100644
index 0000000..2ae23c7
--- /dev/null
+++ b/lib/Target/ARM/ARMInstrInfo.cpp
@@ -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;
+}
diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h
new file mode 100644
index 0000000..b203b22
--- /dev/null
+++ b/lib/Target/ARM/ARMInstrInfo.h
@@ -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
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
new file mode 100644
index 0000000..318c230
--- /dev/null
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -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", []>;
diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp
new file mode 100644
index 0000000..db5ce68
--- /dev/null
+++ b/lib/Target/ARM/ARMRegisterInfo.cpp
@@ -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"
+
diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h
new file mode 100644
index 0000000..a2fa7b9
--- /dev/null
+++ b/lib/Target/ARM/ARMRegisterInfo.h
@@ -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
diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td
new file mode 100644
index 0000000..e53ab8b
--- /dev/null
+++ b/lib/Target/ARM/ARMRegisterInfo.td
@@ -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;
+ }
+ }];
+}
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
new file mode 100644
index 0000000..7520cdc
--- /dev/null
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -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;
+}
+
diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h
new file mode 100644
index 0000000..97d1f22
--- /dev/null
+++ b/lib/Target/ARM/ARMTargetMachine.h
@@ -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
diff --git a/lib/Target/ARM/Makefile b/lib/Target/ARM/Makefile
new file mode 100644
index 0000000..4310b8c
--- /dev/null
+++ b/lib/Target/ARM/Makefile
@@ -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
+
diff --git a/tools/llc/Makefile b/tools/llc/Makefile
index d427715..ed48acc 100644
--- a/tools/llc/Makefile
+++ b/tools/llc/Makefile
@@ -48,6 +48,11 @@
USEDLIBS += LLVMIA64
endif
+#Check for ARM Target
+ifneq ($(strip $(filter ARM,$(TARGETS_TO_BUILD))),)
+USEDLIBS += LLVMARM
+endif
+
USEDLIBS += \
LLVMSelectionDAG \
LLVMCodeGen \