mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 17:29:19 +00:00
Add proper ISD::RET lowering
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70703 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c8fbb6ae20
commit
fd1b7c778c
@ -43,12 +43,15 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
|
||||
|
||||
// Compute derived properties from the register classes
|
||||
computeRegisterProperties();
|
||||
|
||||
setOperationAction(ISD::RET, MVT::Other, Custom);
|
||||
}
|
||||
|
||||
SDValue MSP430TargetLowering::
|
||||
LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
switch (Op.getOpcode()) {
|
||||
case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
|
||||
case ISD::RET: return LowerRET(Op, DAG);
|
||||
default:
|
||||
assert(0 && "unimplemented operand");
|
||||
return SDValue();
|
||||
@ -154,3 +157,58 @@ SDValue MSP430TargetLowering:: LowerCCCArguments(SDValue Op,
|
||||
return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
|
||||
&ArgValues[0], ArgValues.size()).getValue(Op.getResNo());
|
||||
}
|
||||
|
||||
SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
|
||||
// CCValAssign - represent the assignment of the return value to a location
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
|
||||
bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
// CCState - Info about the registers and stack slot.
|
||||
CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs);
|
||||
|
||||
// Analize return values of ISD::RET
|
||||
CCInfo.AnalyzeReturn(Op.getNode(), RetCC_MSP430);
|
||||
|
||||
// If this is the first return lowered for this function, add the regs to the
|
||||
// liveout set for the function.
|
||||
if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i)
|
||||
if (RVLocs[i].isRegLoc())
|
||||
DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
|
||||
}
|
||||
|
||||
// The chain is always operand #0
|
||||
SDValue Chain = Op.getOperand(0);
|
||||
SDValue Flag;
|
||||
|
||||
// Copy the result values into the output registers.
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i) {
|
||||
CCValAssign &VA = RVLocs[i];
|
||||
assert(VA.isRegLoc() && "Can only return in registers!");
|
||||
|
||||
// ISD::RET => ret chain, (regnum1,val1), ...
|
||||
// So i*2+1 index only the regnums
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
|
||||
Op.getOperand(i*2+1), Flag);
|
||||
|
||||
// guarantee that all emitted copies are
|
||||
// stuck together, avoiding something bad
|
||||
Flag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
if (Flag.getNode())
|
||||
return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
|
||||
|
||||
// Return Void
|
||||
return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain);
|
||||
}
|
||||
|
||||
const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
default: return NULL;
|
||||
case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,14 @@
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace MSP430ISD {
|
||||
enum {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
|
||||
/// Return with a flag operand. Operand 0 is the chain operand.
|
||||
RET_FLAG
|
||||
};
|
||||
}
|
||||
|
||||
class MSP430Subtarget;
|
||||
class MSP430TargetMachine;
|
||||
@ -30,7 +38,13 @@ namespace llvm {
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
|
||||
|
||||
/// getTargetNodeName - This method returns the name of a target specific
|
||||
/// DAG node.
|
||||
virtual const char *getTargetNodeName(unsigned Opcode) const;
|
||||
|
||||
SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG);
|
||||
|
||||
private:
|
||||
|
@ -26,9 +26,20 @@ class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MSP430 Specific Node Definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
def retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
|
||||
[SDNPHasChain, SDNPOptInFlag]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pseudo Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def NOP : Pseudo<(outs), (ins), "nop", []>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Real Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// FIXME: Provide proper encoding!
|
||||
let isReturn = 1, isTerminator = 1 in {
|
||||
def RETI: Pseudo<(outs), (ins), "reti", [(retflag)]>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user