aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-12-07 02:27:53 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-12-07 02:27:53 +0000
commite662f7a8b22e7d31fb55e6502af94d49b78bc942 (patch)
tree05ef6f9e66c9503b701d3ab43f5cebd4a01d1060
parent211a14e476abc9b864ab6a5d5e0bbb86d288b650 (diff)
downloadexternal_llvm-e662f7a8b22e7d31fb55e6502af94d49b78bc942.zip
external_llvm-e662f7a8b22e7d31fb55e6502af94d49b78bc942.tar.gz
external_llvm-e662f7a8b22e7d31fb55e6502af94d49b78bc942.tar.bz2
Initial codegen support for MSP430 ISRs
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90739 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp23
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h3
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td9
-rw-r--r--lib/Target/MSP430/MSP430RegisterInfo.cpp27
4 files changed, 54 insertions, 8 deletions
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index 5c4ccc8..801129a 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -254,6 +254,13 @@ MSP430TargetLowering::LowerFormalArguments(SDValue Chain,
case CallingConv::C:
case CallingConv::Fast:
return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
+ case CallingConv::MSP430_INTR:
+ if (Ins.empty())
+ return Chain;
+ else {
+ llvm_report_error("ISRs cannot have arguments");
+ return SDValue();
+ }
}
}
@@ -273,6 +280,9 @@ MSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
case CallingConv::C:
return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
Outs, Ins, dl, DAG, InVals);
+ case CallingConv::MSP430_INTR:
+ llvm_report_error("ISRs cannot be called directly");
+ return SDValue();
}
}
@@ -369,6 +379,12 @@ MSP430TargetLowering::LowerReturn(SDValue Chain,
// CCValAssign - represent the assignment of the return value to a location
SmallVector<CCValAssign, 16> RVLocs;
+ // ISRs cannot return any value.
+ if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) {
+ llvm_report_error("ISRs cannot return any value");
+ return SDValue();
+ }
+
// CCState - Info about the registers and stack slot.
CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
RVLocs, *DAG.getContext());
@@ -399,11 +415,14 @@ MSP430TargetLowering::LowerReturn(SDValue Chain,
Flag = Chain.getValue(1);
}
+ unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
+ MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
+
if (Flag.getNode())
- return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
+ return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag);
// Return Void
- return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain);
+ return DAG.getNode(Opc, dl, MVT::Other, Chain);
}
/// LowerCCCCallTo - functions arguments are copied from virtual regs to
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index d413ccb..6a1a73e 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -27,6 +27,9 @@ namespace llvm {
/// Return with a flag operand. Operand 0 is the chain operand.
RET_FLAG,
+ /// Same as RET_FLAG, but used for returning from ISRs.
+ RETI_FLAG,
+
/// Y = R{R,L}A X, rotate right (left) arithmetically
RRA, RLA,
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index 7a26f6c..3ce0a66 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -35,8 +35,10 @@ def SDT_MSP430SelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSame
//===----------------------------------------------------------------------===//
// MSP430 Specific Node Definitions.
//===----------------------------------------------------------------------===//
-def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
- [SDNPHasChain, SDNPOptInFlag]>;
+def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
+ [SDNPHasChain, SDNPOptInFlag]>;
+def MSP430retiflag : SDNode<"MSP430ISD::RETI_FLAG", SDTNone,
+ [SDNPHasChain, SDNPOptInFlag]>;
def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
@@ -128,7 +130,8 @@ def NOP : Pseudo<(outs), (ins), "nop", []>;
// FIXME: Provide proper encoding!
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
- def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
+ def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
+ def RETI : Pseudo<(outs), (ins), "reti", [(MSP430retiflag)]>;
}
let isBranch = 1, isTerminator = 1 in {
diff --git a/lib/Target/MSP430/MSP430RegisterInfo.cpp b/lib/Target/MSP430/MSP430RegisterInfo.cpp
index 7178440..e85c7a2 100644
--- a/lib/Target/MSP430/MSP430RegisterInfo.cpp
+++ b/lib/Target/MSP430/MSP430RegisterInfo.cpp
@@ -17,6 +17,7 @@
#include "MSP430MachineFunctionInfo.h"
#include "MSP430RegisterInfo.h"
#include "MSP430TargetMachine.h"
+#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -37,17 +38,26 @@ MSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm,
const unsigned*
MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+ const Function* F = MF->getFunction();
static const unsigned CalleeSavedRegs[] = {
MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
0
};
+ static const unsigned CalleeSavedRegsIntr[] = {
+ MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
+ MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
+ MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
+ 0
+ };
- return CalleeSavedRegs;
+ return (F->getCallingConv() == CallingConv::MSP430_INTR ?
+ CalleeSavedRegsIntr : CalleeSavedRegs);
}
const TargetRegisterClass *const *
MSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
+ const Function* F = MF->getFunction();
static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
@@ -55,8 +65,18 @@ MSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
0
};
+ static const TargetRegisterClass * const CalleeSavedRegClassesIntr[] = {
+ &MSP430::GR16RegClass, &MSP430::GR16RegClass,
+ &MSP430::GR16RegClass, &MSP430::GR16RegClass,
+ &MSP430::GR16RegClass, &MSP430::GR16RegClass,
+ &MSP430::GR16RegClass, &MSP430::GR16RegClass,
+ &MSP430::GR16RegClass, &MSP430::GR16RegClass,
+ &MSP430::GR16RegClass, &MSP430::GR16RegClass,
+ 0
+ };
- return CalleeSavedRegClasses;
+ return (F->getCallingConv() == CallingConv::MSP430_INTR ?
+ CalleeSavedRegClassesIntr : CalleeSavedRegClasses);
}
BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
@@ -292,7 +312,8 @@ void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF,
DebugLoc DL = MBBI->getDebugLoc();
switch (RetOpcode) {
- case MSP430::RET: break; // These are ok
+ case MSP430::RET:
+ case MSP430::RETI: break; // These are ok
default:
llvm_unreachable("Can only insert epilog into returning blocks");
}