Initial codegen support for MSP430 ISRs

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90739 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2009-12-07 02:27:53 +00:00
parent 211a14e476
commit e662f7a8b2
4 changed files with 54 additions and 8 deletions

View File

@ -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

View File

@ -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,

View File

@ -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 {

View File

@ -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");
}