From 2e2ecfb186cabf2522a35f109f2fa156f3b72289 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Wed, 5 Aug 2015 00:22:22 -0400 Subject: [PATCH] More implementation of LowerFormalArguments() and LowerReturn() --- lib/Target/WDC65816/WDC65816ISelLowering.cpp | 551 +++---------------- lib/Target/WDC65816/WDC65816ISelLowering.h | 8 +- lib/Target/WDC65816/WDC65816InstrInfo.td | 7 +- 3 files changed, 87 insertions(+), 479 deletions(-) diff --git a/lib/Target/WDC65816/WDC65816ISelLowering.cpp b/lib/Target/WDC65816/WDC65816ISelLowering.cpp index 974f1ee8..0493f364 100644 --- a/lib/Target/WDC65816/WDC65816ISelLowering.cpp +++ b/lib/Target/WDC65816/WDC65816ISelLowering.cpp @@ -45,8 +45,6 @@ SDValue WDC65816TargetLowering::LowerFormalArguments(SDValue Chain, SDLoc DL, SelectionDAG &DAG, SmallVectorImpl &InVals) const { - WDC_LOG("WDC_TODO - Not fully implemented yet!"); - MachineFunction &MF = DAG.getMachineFunction(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); WDC65816MachineFunctionInfo *FuncInfo = MF.getInfo(); @@ -57,6 +55,43 @@ SDValue WDC65816TargetLowering::LowerFormalArguments(SDValue Chain, getTargetMachine(), ArgLocs, *DAG.getContext()); CCInfo.AnalyzeFormalArguments(Ins, CC_WDC); + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + CCValAssign &VA = ArgLocs[i]; + + if (i == 0 && Ins[i].Flags.isSRet()) { + WDC_LOG("WDC_TODO - Write code for returning a structure as a hidden input arg pointer"); + continue; + } + + if (VA.isRegLoc()) { + if (VA.needsCustom()) { + WDC_LOG("WDC_TODO - needsCustom() in register location!"); + continue; + } + WDC_LOG("WDC_TODO - Write code for register location"); + continue; + } + + assert(VA.isMemLoc()); + + unsigned Offset = VA.getLocMemOffset(); + + if (VA.needsCustom()) { + WDC_LOG("WDC_TODO - needsCustom() in memory location, offset=%u!", Offset); + continue; + } + + WDC_LOG("WDC_TODO - Write code for memory location, offset=%u", Offset); + } + + if (MF.getFunction()->hasStructRetAttr()) { + WDC_LOG("WDC_TODO - Write code for hasStructRetAttr()"); + } + + if (isVarArg) { + WDC_LOG("WDC_TODO - Write code for isVarArg"); + } + return Chain; } @@ -67,8 +102,47 @@ WDC65816TargetLowering::LowerReturn(SDValue Chain, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, SDLoc DL, SelectionDAG &DAG) const { - WDC_LOG("WDC_TODO - Not implemented yet!"); - return Chain; + MachineFunction &MF = DAG.getMachineFunction(); + + // CCValAssign - represent the assignment of the return value to locations. + SmallVector RVLocs; + + // CCState - Info about the registers and stack slot. + CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), + DAG.getTarget(), RVLocs, *DAG.getContext()); + + // Analyze return values. + CCInfo.AnalyzeReturn(Outs, RetCC_WDC); + + SDValue Flag; + SmallVector RetOps(1, Chain); + + // 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!"); + + Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), + OutVals[i], Flag); + + // Guarantee that all emitted copies are stuck together with flags. + Flag = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); + } + + // If the function returns a struct, copy the SRetReturnReg to I0 + if (MF.getFunction()->hasStructRetAttr()) { + WDC_LOG("WDC_TODO - Need to implement hasStructRetAttr() case"); + } + + RetOps[0] = Chain; // Update chain. + + // Add the flag if we have it. + if (Flag.getNode()) + RetOps.push_back(Flag); + + return DAG.getNode(WDCISD::RET_FLAG, DL, MVT::Other, + &RetOps[0], RetOps.size()); } @@ -86,475 +160,6 @@ static unsigned toCallerWindow(unsigned Reg) { #if 0 // WDC_TODO - Disable more stuff -SDValue -WDC65816TargetLowering::LowerReturn_32(SDValue Chain, - CallingConv::ID CallConv, bool IsVarArg, - const SmallVectorImpl &Outs, - const SmallVectorImpl &OutVals, - SDLoc DL, SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - - // CCValAssign - represent the assignment of the return value to locations. - SmallVector RVLocs; - - // CCState - Info about the registers and stack slot. - CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), - DAG.getTarget(), RVLocs, *DAG.getContext()); - - // Analyze return values. - CCInfo.AnalyzeReturn(Outs, RetCC_WDC6581632); - - SDValue Flag; - SmallVector RetOps(1, Chain); - // Make room for the return address offset. - RetOps.push_back(SDValue()); - - // 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!"); - - Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), - OutVals[i], Flag); - - // Guarantee that all emitted copies are stuck together with flags. - Flag = Chain.getValue(1); - RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); - } - - unsigned RetAddrOffset = 8; // Call Inst + Delay Slot - // If the function returns a struct, copy the SRetReturnReg to I0 - if (MF.getFunction()->hasStructRetAttr()) { - WDC65816MachineFunctionInfo *SFI = MF.getInfo(); - unsigned Reg = SFI->getSRetReturnReg(); - if (!Reg) - llvm_unreachable("sret virtual register not created in the entry block"); - SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy()); - Chain = DAG.getCopyToReg(Chain, DL, SP::I0, Val, Flag); - Flag = Chain.getValue(1); - RetOps.push_back(DAG.getRegister(SP::I0, getPointerTy())); - RetAddrOffset = 12; // CallInst + Delay Slot + Unimp - } - - RetOps[0] = Chain; // Update chain. - RetOps[1] = DAG.getConstant(RetAddrOffset, MVT::i32); - - // Add the flag if we have it. - if (Flag.getNode()) - RetOps.push_back(Flag); - - return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, - &RetOps[0], RetOps.size()); -} - -// Lower return values for the 64-bit ABI. -// Return values are passed the exactly the same way as function arguments. -SDValue -WDC65816TargetLowering::LowerReturn_64(SDValue Chain, - CallingConv::ID CallConv, bool IsVarArg, - const SmallVectorImpl &Outs, - const SmallVectorImpl &OutVals, - SDLoc DL, SelectionDAG &DAG) const { - // CCValAssign - represent the assignment of the return value to locations. - SmallVector RVLocs; - - // CCState - Info about the registers and stack slot. - CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), - DAG.getTarget(), RVLocs, *DAG.getContext()); - - // Analyze return values. - CCInfo.AnalyzeReturn(Outs, CC_WDC6581664); - - SDValue Flag; - SmallVector RetOps(1, Chain); - - // The second operand on the return instruction is the return address offset. - // The return address is always %i7+8 with the 64-bit ABI. - RetOps.push_back(DAG.getConstant(8, MVT::i32)); - - // 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!"); - SDValue OutVal = OutVals[i]; - - // Integer return values must be sign or zero extended by the callee. - switch (VA.getLocInfo()) { - case CCValAssign::SExt: - OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal); - break; - case CCValAssign::ZExt: - OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal); - break; - case CCValAssign::AExt: - OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal); - default: - break; - } - - // The custom bit on an i32 return value indicates that it should be passed - // in the high bits of the register. - if (VA.getValVT() == MVT::i32 && VA.needsCustom()) { - OutVal = DAG.getNode(ISD::SHL, DL, MVT::i64, OutVal, - DAG.getConstant(32, MVT::i32)); - - // The next value may go in the low bits of the same register. - // Handle both at once. - if (i+1 < RVLocs.size() && RVLocs[i+1].getLocReg() == VA.getLocReg()) { - SDValue NV = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, OutVals[i+1]); - OutVal = DAG.getNode(ISD::OR, DL, MVT::i64, OutVal, NV); - // Skip the next value, it's already done. - ++i; - } - } - - Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag); - - // Guarantee that all emitted copies are stuck together with flags. - Flag = Chain.getValue(1); - RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); - } - - RetOps[0] = Chain; // Update chain. - - // Add the flag if we have it. - if (Flag.getNode()) - RetOps.push_back(Flag); - - return DAG.getNode(SPISD::RET_FLAG, DL, MVT::Other, - &RetOps[0], RetOps.size()); -} - -SDValue WDC65816TargetLowering:: -LowerFormalArguments(SDValue Chain, - CallingConv::ID CallConv, - bool IsVarArg, - const SmallVectorImpl &Ins, - SDLoc DL, - SelectionDAG &DAG, - SmallVectorImpl &InVals) const { - if (Subtarget->is64Bit()) - return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins, - DL, DAG, InVals); - return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins, - DL, DAG, InVals); -} - -/// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are -/// passed in either one or two GPRs, including FP values. TODO: we should -/// pass FP values in FP registers for fastcc functions. -SDValue WDC65816TargetLowering:: -LowerFormalArguments_32(SDValue Chain, - CallingConv::ID CallConv, - bool isVarArg, - const SmallVectorImpl &Ins, - SDLoc dl, - SelectionDAG &DAG, - SmallVectorImpl &InVals) const { - MachineFunction &MF = DAG.getMachineFunction(); - MachineRegisterInfo &RegInfo = MF.getRegInfo(); - WDC65816MachineFunctionInfo *FuncInfo = MF.getInfo(); - - // Assign locations to all of the incoming arguments. - SmallVector ArgLocs; - CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), - getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Ins, CC_WDC6581632); - - const unsigned StackOffset = 92; - - for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { - CCValAssign &VA = ArgLocs[i]; - - if (i == 0 && Ins[i].Flags.isSRet()) { - // Get SRet from [%fp+64]. - int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true); - SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); - SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, - MachinePointerInfo(), - false, false, false, 0); - InVals.push_back(Arg); - continue; - } - - if (VA.isRegLoc()) { - if (VA.needsCustom()) { - assert(VA.getLocVT() == MVT::f64); - unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); - MF.getRegInfo().addLiveIn(VA.getLocReg(), VRegHi); - SDValue HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32); - - assert(i+1 < e); - CCValAssign &NextVA = ArgLocs[++i]; - - SDValue LoVal; - if (NextVA.isMemLoc()) { - int FrameIdx = MF.getFrameInfo()-> - CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true); - SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); - LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, - MachinePointerInfo(), - false, false, false, 0); - } else { - unsigned loReg = MF.addLiveIn(NextVA.getLocReg(), - &SP::IntRegsRegClass); - LoVal = DAG.getCopyFromReg(Chain, dl, loReg, MVT::i32); - } - SDValue WholeValue = - DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); - WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue); - InVals.push_back(WholeValue); - continue; - } - unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); - MF.getRegInfo().addLiveIn(VA.getLocReg(), VReg); - SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); - if (VA.getLocVT() == MVT::f32) - Arg = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Arg); - else if (VA.getLocVT() != MVT::i32) { - Arg = DAG.getNode(ISD::AssertSext, dl, MVT::i32, Arg, - DAG.getValueType(VA.getLocVT())); - Arg = DAG.getNode(ISD::TRUNCATE, dl, VA.getLocVT(), Arg); - } - InVals.push_back(Arg); - continue; - } - - assert(VA.isMemLoc()); - - unsigned Offset = VA.getLocMemOffset()+StackOffset; - - if (VA.needsCustom()) { - assert(VA.getValVT() == MVT::f64); - // If it is double-word aligned, just load. - if (Offset % 8 == 0) { - int FI = MF.getFrameInfo()->CreateFixedObject(8, - Offset, - true); - SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); - SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, - MachinePointerInfo(), - false,false, false, 0); - InVals.push_back(Load); - continue; - } - - int FI = MF.getFrameInfo()->CreateFixedObject(4, - Offset, - true); - SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); - SDValue HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, - MachinePointerInfo(), - false, false, false, 0); - int FI2 = MF.getFrameInfo()->CreateFixedObject(4, - Offset+4, - true); - SDValue FIPtr2 = DAG.getFrameIndex(FI2, getPointerTy()); - - SDValue LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr2, - MachinePointerInfo(), - false, false, false, 0); - - SDValue WholeValue = - DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, LoVal, HiVal); - WholeValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, WholeValue); - InVals.push_back(WholeValue); - continue; - } - - int FI = MF.getFrameInfo()->CreateFixedObject(4, - Offset, - true); - SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); - SDValue Load ; - if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) { - Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, - MachinePointerInfo(), - false, false, false, 0); - } else { - ISD::LoadExtType LoadOp = ISD::SEXTLOAD; - // WDC65816 is big endian, so add an offset based on the ObjectVT. - unsigned Offset = 4-std::max(1U, VA.getValVT().getSizeInBits()/8); - FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr, - DAG.getConstant(Offset, MVT::i32)); - Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr, - MachinePointerInfo(), - VA.getValVT(), false, false,0); - Load = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), Load); - } - InVals.push_back(Load); - } - - if (MF.getFunction()->hasStructRetAttr()) { - // Copy the SRet Argument to SRetReturnReg. - WDC65816MachineFunctionInfo *SFI = MF.getInfo(); - unsigned Reg = SFI->getSRetReturnReg(); - if (!Reg) { - Reg = MF.getRegInfo().createVirtualRegister(&SP::IntRegsRegClass); - SFI->setSRetReturnReg(Reg); - } - SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); - } - - // Store remaining ArgRegs to the stack if this is a varargs function. - if (isVarArg) { - static const uint16_t ArgRegs[] = { - SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 - }; - unsigned NumAllocated = CCInfo.getFirstUnallocated(ArgRegs, 6); - const uint16_t *CurArgReg = ArgRegs+NumAllocated, *ArgRegEnd = ArgRegs+6; - unsigned ArgOffset = CCInfo.getNextStackOffset(); - if (NumAllocated == 6) - ArgOffset += StackOffset; - else { - assert(!ArgOffset); - ArgOffset = 68+4*NumAllocated; - } - - // Remember the vararg offset for the va_start implementation. - FuncInfo->setVarArgsFrameOffset(ArgOffset); - - std::vector OutChains; - - for (; CurArgReg != ArgRegEnd; ++CurArgReg) { - unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); - MF.getRegInfo().addLiveIn(*CurArgReg, VReg); - SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32); - - int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset, - true); - SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); - - OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, - MachinePointerInfo(), - false, false, 0)); - ArgOffset += 4; - } - - if (!OutChains.empty()) { - OutChains.push_back(Chain); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &OutChains[0], OutChains.size()); - } - } - - return Chain; -} - -// Lower formal arguments for the 64 bit ABI. -SDValue WDC65816TargetLowering:: -LowerFormalArguments_64(SDValue Chain, - CallingConv::ID CallConv, - bool IsVarArg, - const SmallVectorImpl &Ins, - SDLoc DL, - SelectionDAG &DAG, - SmallVectorImpl &InVals) const { - MachineFunction &MF = DAG.getMachineFunction(); - - // Analyze arguments according to CC_WDC6581664. - SmallVector ArgLocs; - CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), - getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Ins, CC_WDC6581664); - - // The argument array begins at %fp+BIAS+128, after the register save area. - const unsigned ArgArea = 128; - - for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { - CCValAssign &VA = ArgLocs[i]; - if (VA.isRegLoc()) { - // This argument is passed in a register. - // All integer register arguments are promoted by the caller to i64. - - // Create a virtual register for the promoted live-in value. - unsigned VReg = MF.addLiveIn(VA.getLocReg(), - getRegClassFor(VA.getLocVT())); - SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT()); - - // Get the high bits for i32 struct elements. - if (VA.getValVT() == MVT::i32 && VA.needsCustom()) - Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg, - DAG.getConstant(32, MVT::i32)); - - // The caller promoted the argument, so insert an Assert?ext SDNode so we - // won't promote the value again in this function. - switch (VA.getLocInfo()) { - case CCValAssign::SExt: - Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg, - DAG.getValueType(VA.getValVT())); - break; - case CCValAssign::ZExt: - Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg, - DAG.getValueType(VA.getValVT())); - break; - default: - break; - } - - // Truncate the register down to the argument type. - if (VA.isExtInLoc()) - Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg); - - InVals.push_back(Arg); - continue; - } - - // The registers are exhausted. This argument was passed on the stack. - assert(VA.isMemLoc()); - // The CC_WDC6581664_Full/Half functions compute stack offsets relative to the - // beginning of the arguments area at %fp+BIAS+128. - unsigned Offset = VA.getLocMemOffset() + ArgArea; - unsigned ValSize = VA.getValVT().getSizeInBits() / 8; - // Adjust offset for extended arguments, WDC65816 is big-endian. - // The caller will have written the full slot with extended bytes, but we - // prefer our own extending loads. - if (VA.isExtInLoc()) - Offset += 8 - ValSize; - int FI = MF.getFrameInfo()->CreateFixedObject(ValSize, Offset, true); - InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, - DAG.getFrameIndex(FI, getPointerTy()), - MachinePointerInfo::getFixedStack(FI), - false, false, false, 0)); - } - - if (!IsVarArg) - return Chain; - - // This function takes variable arguments, some of which may have been passed - // in registers %i0-%i5. Variable floating point arguments are never passed - // in floating point registers. They go on %i0-%i5 or on the stack like - // integer arguments. - // - // The va_start intrinsic needs to know the offset to the first variable - // argument. - unsigned ArgOffset = CCInfo.getNextStackOffset(); - WDC65816MachineFunctionInfo *FuncInfo = MF.getInfo(); - // Skip the 128 bytes of register save area. - FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgArea + - Subtarget->getStackPointerBias()); - - // Save the variable arguments that were passed in registers. - // The caller is required to reserve stack space for 6 arguments regardless - // of how many arguments were actually passed. - SmallVector OutChains; - for (; ArgOffset < 6*8; ArgOffset += 8) { - unsigned VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass); - SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64); - int FI = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset + ArgArea, true); - OutChains.push_back(DAG.getStore(Chain, DL, VArg, - DAG.getFrameIndex(FI, getPointerTy()), - MachinePointerInfo::getFixedStack(FI), - false, false, 0)); - } - - if (!OutChains.empty()) - Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, - &OutChains[0], OutChains.size()); - - return Chain; -} SDValue WDC65816TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, diff --git a/lib/Target/WDC65816/WDC65816ISelLowering.h b/lib/Target/WDC65816/WDC65816ISelLowering.h index 1c45323f..1564114b 100644 --- a/lib/Target/WDC65816/WDC65816ISelLowering.h +++ b/lib/Target/WDC65816/WDC65816ISelLowering.h @@ -20,10 +20,11 @@ namespace llvm { class WDC65816Subtarget; -#if 0 // WDC_TODO - Do I need any of this? - namespace SPISD { + namespace WDCISD { enum { FIRST_NUMBER = ISD::BUILTIN_OP_END, + RET_FLAG, // Return with a flag operand. +#if 0 CMPICC, // Compare two GPR operands, set icc+xcc. CMPFCC, // Compare two FP operands, set fcc. BRICC, // Branch to dest on icc condition @@ -41,16 +42,15 @@ namespace llvm { XTOF, // Int64 to FP within a FP register. CALL, // A call instruction. - RET_FLAG, // Return with a flag operand. GLOBAL_BASE_REG, // Global base reg for PIC. FLUSHW, // FLUSH register windows to stack. TLS_ADD, // For Thread Local Storage (TLS). TLS_LD, TLS_CALL +#endif }; } -#endif class WDC65816TargetLowering : public TargetLowering { const WDC65816Subtarget *Subtarget; diff --git a/lib/Target/WDC65816/WDC65816InstrInfo.td b/lib/Target/WDC65816/WDC65816InstrInfo.td index 1c1fe5ac..595666ff 100644 --- a/lib/Target/WDC65816/WDC65816InstrInfo.td +++ b/lib/Target/WDC65816/WDC65816InstrInfo.td @@ -100,6 +100,8 @@ let Defs = [S], Uses = [S] in { [(callseq_end timm:$amt1, timm:$amt2)]>; } +def WDCRET : SDNode<"WDCISD::RET_FLAG", SDTNone, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; + // Group #1 Instructions // JSR TODO - Need to set all of the DAG patterns @@ -1248,11 +1250,12 @@ def RTI : Group3; - +let isReturn = 1, isTerminator = 1, isBarrier = 1 in { def RTL : Group3; + [(WDCRET)]>; +} def RTS : Group3