mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-18 10:24:45 +00:00
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:
@@ -254,6 +254,13 @@ MSP430TargetLowering::LowerFormalArguments(SDValue Chain,
|
|||||||
case CallingConv::C:
|
case CallingConv::C:
|
||||||
case CallingConv::Fast:
|
case CallingConv::Fast:
|
||||||
return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
|
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:
|
case CallingConv::C:
|
||||||
return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
|
return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
|
||||||
Outs, Ins, dl, DAG, InVals);
|
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
|
// CCValAssign - represent the assignment of the return value to a location
|
||||||
SmallVector<CCValAssign, 16> RVLocs;
|
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 - Info about the registers and stack slot.
|
||||||
CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
|
CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
|
||||||
RVLocs, *DAG.getContext());
|
RVLocs, *DAG.getContext());
|
||||||
@@ -399,11 +415,14 @@ MSP430TargetLowering::LowerReturn(SDValue Chain,
|
|||||||
Flag = Chain.getValue(1);
|
Flag = Chain.getValue(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
|
||||||
|
MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
|
||||||
|
|
||||||
if (Flag.getNode())
|
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 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
|
/// LowerCCCCallTo - functions arguments are copied from virtual regs to
|
||||||
|
@@ -27,6 +27,9 @@ namespace llvm {
|
|||||||
/// Return with a flag operand. Operand 0 is the chain operand.
|
/// Return with a flag operand. Operand 0 is the chain operand.
|
||||||
RET_FLAG,
|
RET_FLAG,
|
||||||
|
|
||||||
|
/// Same as RET_FLAG, but used for returning from ISRs.
|
||||||
|
RETI_FLAG,
|
||||||
|
|
||||||
/// Y = R{R,L}A X, rotate right (left) arithmetically
|
/// Y = R{R,L}A X, rotate right (left) arithmetically
|
||||||
RRA, RLA,
|
RRA, RLA,
|
||||||
|
|
||||||
|
@@ -37,6 +37,8 @@ def SDT_MSP430SelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSame
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
|
def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
|
||||||
[SDNPHasChain, SDNPOptInFlag]>;
|
[SDNPHasChain, SDNPOptInFlag]>;
|
||||||
|
def MSP430retiflag : SDNode<"MSP430ISD::RETI_FLAG", SDTNone,
|
||||||
|
[SDNPHasChain, SDNPOptInFlag]>;
|
||||||
|
|
||||||
def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
|
def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
|
||||||
def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
|
def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
|
||||||
@@ -129,6 +131,7 @@ def NOP : Pseudo<(outs), (ins), "nop", []>;
|
|||||||
// FIXME: Provide proper encoding!
|
// FIXME: Provide proper encoding!
|
||||||
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
|
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 {
|
let isBranch = 1, isTerminator = 1 in {
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "MSP430MachineFunctionInfo.h"
|
#include "MSP430MachineFunctionInfo.h"
|
||||||
#include "MSP430RegisterInfo.h"
|
#include "MSP430RegisterInfo.h"
|
||||||
#include "MSP430TargetMachine.h"
|
#include "MSP430TargetMachine.h"
|
||||||
|
#include "llvm/Function.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
@@ -37,17 +38,26 @@ MSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm,
|
|||||||
|
|
||||||
const unsigned*
|
const unsigned*
|
||||||
MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||||
|
const Function* F = MF->getFunction();
|
||||||
static const unsigned CalleeSavedRegs[] = {
|
static const unsigned CalleeSavedRegs[] = {
|
||||||
MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
|
MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
|
||||||
MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
|
MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
|
||||||
0
|
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 *
|
const TargetRegisterClass *const *
|
||||||
MSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
|
MSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
|
||||||
|
const Function* F = MF->getFunction();
|
||||||
static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
|
static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
|
||||||
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
|
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
|
||||||
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
|
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
|
||||||
@@ -55,8 +65,18 @@ MSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
|
|||||||
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
|
&MSP430::GR16RegClass, &MSP430::GR16RegClass,
|
||||||
0
|
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 {
|
BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||||
@@ -292,7 +312,8 @@ void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
DebugLoc DL = MBBI->getDebugLoc();
|
DebugLoc DL = MBBI->getDebugLoc();
|
||||||
|
|
||||||
switch (RetOpcode) {
|
switch (RetOpcode) {
|
||||||
case MSP430::RET: break; // These are ok
|
case MSP430::RET:
|
||||||
|
case MSP430::RETI: break; // These are ok
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Can only insert epilog into returning blocks");
|
llvm_unreachable("Can only insert epilog into returning blocks");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user