mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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:
parent
a3fdc02466
commit
7bc59bc395
@ -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
2
configure
vendored
@ -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
40
lib/Target/ARM/ARM.h
Normal 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
51
lib/Target/ARM/ARM.td
Normal 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;
|
||||
}
|
115
lib/Target/ARM/ARMAsmPrinter.cpp
Normal file
115
lib/Target/ARM/ARMAsmPrinter.cpp
Normal 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
|
||||
}
|
137
lib/Target/ARM/ARMISelDAGToDAG.cpp
Normal file
137
lib/Target/ARM/ARMISelDAGToDAG.cpp
Normal 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);
|
||||
}
|
58
lib/Target/ARM/ARMInstrInfo.cpp
Normal file
58
lib/Target/ARM/ARMInstrInfo.cpp
Normal 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;
|
||||
}
|
57
lib/Target/ARM/ARMInstrInfo.h
Normal file
57
lib/Target/ARM/ARMInstrInfo.h
Normal 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
|
54
lib/Target/ARM/ARMInstrInfo.td
Normal file
54
lib/Target/ARM/ARMInstrInfo.td
Normal 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", []>;
|
91
lib/Target/ARM/ARMRegisterInfo.cpp
Normal file
91
lib/Target/ARM/ARMRegisterInfo.cpp
Normal 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"
|
||||
|
66
lib/Target/ARM/ARMRegisterInfo.h
Normal file
66
lib/Target/ARM/ARMRegisterInfo.h
Normal 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
|
56
lib/Target/ARM/ARMRegisterInfo.td
Normal file
56
lib/Target/ARM/ARMRegisterInfo.td
Normal 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;
|
||||
}
|
||||
}];
|
||||
}
|
99
lib/Target/ARM/ARMTargetMachine.cpp
Normal file
99
lib/Target/ARM/ARMTargetMachine.cpp
Normal 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;
|
||||
}
|
||||
|
49
lib/Target/ARM/ARMTargetMachine.h
Normal file
49
lib/Target/ARM/ARMTargetMachine.h
Normal 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
21
lib/Target/ARM/Makefile
Normal 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
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user