aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:07:54 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:07:54 +0000
commitb561264d2b2e33e1e6322a99d600b5daece5bbde (patch)
treee7f4636b0381e8fef9a324f2330c66c842ee655b /lib/Target
parent4428885c5acfffbbdd03ad2aab23960531c47753 (diff)
downloadexternal_llvm-b561264d2b2e33e1e6322a99d600b5daece5bbde.zip
external_llvm-b561264d2b2e33e1e6322a99d600b5daece5bbde.tar.gz
external_llvm-b561264d2b2e33e1e6322a99d600b5daece5bbde.tar.bz2
Add call frame setup instruction elimination and lowerid for bunch of call-related stuff.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70728 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp1
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.cpp2
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td49
-rw-r--r--lib/Target/MSP430/MSP430RegisterInfo.cpp73
-rw-r--r--lib/Target/MSP430/MSP430RegisterInfo.h13
5 files changed, 127 insertions, 11 deletions
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index a5af55c..ab8be5a 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -426,5 +426,6 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
default: return NULL;
case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG";
case MSP430ISD::RRA: return "MSP430ISD::RRA";
+ case MSP430ISD::CALL: return "MSP430ISD::CALL";
}
}
diff --git a/lib/Target/MSP430/MSP430InstrInfo.cpp b/lib/Target/MSP430/MSP430InstrInfo.cpp
index 579da6e..dbbf29c 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.cpp
+++ b/lib/Target/MSP430/MSP430InstrInfo.cpp
@@ -25,7 +25,7 @@ using namespace llvm;
MSP430InstrInfo::MSP430InstrInfo(MSP430TargetMachine &tm)
: TargetInstrInfoImpl(MSP430Insts, array_lengthof(MSP430Insts)),
- RI(*this), TM(tm) {}
+ RI(tm, *this), TM(tm) {}
bool MSP430InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index 442060c..1f13f2d 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -22,7 +22,9 @@ class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
//===----------------------------------------------------------------------===//
// Type Profiles.
//===----------------------------------------------------------------------===//
-def SDT_MSP430Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
+def SDT_MSP430Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
+def SDT_MSP430CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>]>;
+def SDT_MSP430CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>;
//===----------------------------------------------------------------------===//
// MSP430 Specific Node Definitions.
@@ -34,6 +36,12 @@ def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
def MSP430call : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
[SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
+def MSP430callseq_start :
+ SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
+ [SDNPHasChain, SDNPOutFlag]>;
+def MSP430callseq_end :
+ SDNode<"ISD::CALLSEQ_END", SDT_MSP430CallSeqEnd,
+ [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
//===----------------------------------------------------------------------===//
// MSP430 Operand Definitions.
@@ -63,20 +71,49 @@ def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
//===----------------------------------------------------------------------===//
-// Pseudo Instructions
+// Instruction list..
+
+// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
+// a stack adjustment and the codegen must know that they may modify the stack
+// pointer before prolog-epilog rewriting occurs.
+// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
+// sub / add which can clobber SRW.
+let Defs = [SPW, SRW], Uses = [SPW] in {
+def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
+ "#ADJCALLSTACKDOWN",
+ [(MSP430callseq_start timm:$amt)]>;
+def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
+ "#ADJCALLSTACKUP",
+ [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
+}
+
let neverHasSideEffects = 1 in
def NOP : Pseudo<(outs), (ins), "nop", []>;
-//===----------------------------------------------------------------------===//
-// Real Instructions
-
// FIXME: Provide proper encoding!
let isReturn = 1, isTerminator = 1 in {
- def RETI : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
+ def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
}
//===----------------------------------------------------------------------===//
+// Call Instructions...
+//
+let isCall = 1 in
+ // All calls clobber the non-callee saved registers. SPW is marked as
+ // a use to prevent stack-pointer assignments that appear immediately
+ // before calls from potentially appearing dead. Uses for argument
+ // registers are added manually.
+ let Defs = [R12W, R13W, R14W, R15W, SRW],
+ Uses = [SPW] in {
+ def CALL32r : Pseudo<(outs), (ins GR16:$dst, variable_ops),
+ "call\t{*}$dst", [(MSP430call GR16:$dst)]>;
+ def CALL32m : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
+ "call\t{*}$dst", [(MSP430call (load addr:$dst))]>;
+ }
+
+
+//===----------------------------------------------------------------------===//
// Move Instructions
// FIXME: Provide proper encoding!
diff --git a/lib/Target/MSP430/MSP430RegisterInfo.cpp b/lib/Target/MSP430/MSP430RegisterInfo.cpp
index 292dd28..c7efa5e 100644
--- a/lib/Target/MSP430/MSP430RegisterInfo.cpp
+++ b/lib/Target/MSP430/MSP430RegisterInfo.cpp
@@ -15,8 +15,10 @@
#include "MSP430.h"
#include "MSP430RegisterInfo.h"
+#include "MSP430TargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/BitVector.h"
@@ -24,9 +26,12 @@
using namespace llvm;
// FIXME: Provide proper call frame setup / destroy opcodes.
-MSP430RegisterInfo::MSP430RegisterInfo(const TargetInstrInfo &tii)
- : MSP430GenRegisterInfo(MSP430::NOP, MSP430::NOP),
- TII(tii) {}
+MSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm,
+ const TargetInstrInfo &tii)
+ : MSP430GenRegisterInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
+ TM(tm), TII(tii) {
+ StackAlign = TM.getFrameInfo()->getStackAlignment();
+}
const unsigned*
MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
@@ -73,6 +78,68 @@ bool MSP430RegisterInfo::hasFP(const MachineFunction &MF) const {
return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
}
+bool MSP430RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
+ return !MF.getFrameInfo()->hasVarSizedObjects();
+}
+
+void MSP430RegisterInfo::
+eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I) const {
+ if (!hasReservedCallFrame(MF)) {
+ // If the stack pointer can be changed after prologue, turn the
+ // adjcallstackup instruction into a 'sub SPW, <amt>' and the
+ // adjcallstackdown instruction into 'add SPW, <amt>'
+ // TODO: consider using push / pop instead of sub + store / add
+ MachineInstr *Old = I;
+ uint64_t Amount = Old->getOperand(0).getImm();
+ if (Amount != 0) {
+ // We need to keep the stack aligned properly. To do this, we round the
+ // amount of space needed for the outgoing arguments up to the next
+ // alignment boundary.
+ Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
+
+ MachineInstr *New = 0;
+ if (Old->getOpcode() == getCallFrameSetupOpcode()) {
+ New = BuildMI(MF, Old->getDebugLoc(),
+ TII.get(MSP430::SUB16ri), MSP430::SPW)
+ .addReg(MSP430::SPW).addImm(Amount);
+ } else {
+ assert(Old->getOpcode() == getCallFrameDestroyOpcode());
+ // factor out the amount the callee already popped.
+ uint64_t CalleeAmt = Old->getOperand(1).getImm();
+ Amount -= CalleeAmt;
+ if (Amount)
+ New = BuildMI(MF, Old->getDebugLoc(),
+ TII.get(MSP430::ADD16ri), MSP430::SPW)
+ .addReg(MSP430::SPW).addImm(Amount);
+ }
+
+ if (New) {
+ // The SRW implicit def is dead.
+ New->getOperand(3).setIsDead();
+
+ // Replace the pseudo instruction with a new instruction...
+ MBB.insert(I, New);
+ }
+ }
+ } else if (I->getOpcode() == getCallFrameDestroyOpcode()) {
+ // If we are performing frame pointer elimination and if the callee pops
+ // something off the stack pointer, add it back.
+ if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
+ MachineInstr *Old = I;
+ MachineInstr *New =
+ BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
+ MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
+ // The SRW implicit def is dead.
+ New->getOperand(3).setIsDead();
+
+ MBB.insert(I, New);
+ }
+ }
+
+ MBB.erase(I);
+}
+
void
MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS) const {
diff --git a/lib/Target/MSP430/MSP430RegisterInfo.h b/lib/Target/MSP430/MSP430RegisterInfo.h
index f1c4095..0dc061c 100644
--- a/lib/Target/MSP430/MSP430RegisterInfo.h
+++ b/lib/Target/MSP430/MSP430RegisterInfo.h
@@ -20,12 +20,18 @@
namespace llvm {
class TargetInstrInfo;
+class MSP430TargetMachine;
struct MSP430RegisterInfo : public MSP430GenRegisterInfo {
private:
+ MSP430TargetMachine &TM;
const TargetInstrInfo &TII;
+
+ /// StackAlign - Default stack alignment.
+ ///
+ unsigned StackAlign;
public:
- MSP430RegisterInfo(const TargetInstrInfo &tii);
+ MSP430RegisterInfo(MSP430TargetMachine &tm, const TargetInstrInfo &tii);
/// Code Generation virtual methods...
const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
@@ -36,6 +42,11 @@ public:
BitVector getReservedRegs(const MachineFunction &MF) const;
bool hasFP(const MachineFunction &MF) const;
+ bool hasReservedCallFrame(MachineFunction &MF) const;
+
+ void eliminateCallFramePseudoInstr(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS = NULL) const;