mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-23 20:34:58 +00:00
Add support for varargs functions for msp430.
Patch by Job Noorman! llvm-svn: 168440
This commit is contained in:
parent
1a8ff7b99a
commit
a96a1c8e42
@ -164,6 +164,12 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
|
|||||||
setOperationAction(ISD::SDIVREM, MVT::i16, Expand);
|
setOperationAction(ISD::SDIVREM, MVT::i16, Expand);
|
||||||
setOperationAction(ISD::SREM, MVT::i16, Expand);
|
setOperationAction(ISD::SREM, MVT::i16, Expand);
|
||||||
|
|
||||||
|
// varargs support
|
||||||
|
setOperationAction(ISD::VASTART, MVT::Other, Custom);
|
||||||
|
setOperationAction(ISD::VAARG, MVT::Other, Expand);
|
||||||
|
setOperationAction(ISD::VAEND, MVT::Other, Expand);
|
||||||
|
setOperationAction(ISD::VACOPY, MVT::Other, Expand);
|
||||||
|
|
||||||
// Libcalls names.
|
// Libcalls names.
|
||||||
if (HWMultMode == HWMultIntr) {
|
if (HWMultMode == HWMultIntr) {
|
||||||
setLibcallName(RTLIB::MUL_I8, "__mulqi3hw");
|
setLibcallName(RTLIB::MUL_I8, "__mulqi3hw");
|
||||||
@ -192,6 +198,7 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op,
|
|||||||
case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
|
case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
|
||||||
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
||||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||||
|
case ISD::VASTART: return LowerVASTART(Op, DAG);
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("unimplemented operand");
|
llvm_unreachable("unimplemented operand");
|
||||||
}
|
}
|
||||||
@ -297,7 +304,6 @@ MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||||||
/// LowerCCCArguments - transform physical registers into virtual registers and
|
/// LowerCCCArguments - transform physical registers into virtual registers and
|
||||||
/// generate load operations for arguments places on the stack.
|
/// generate load operations for arguments places on the stack.
|
||||||
// FIXME: struct return stuff
|
// FIXME: struct return stuff
|
||||||
// FIXME: varargs
|
|
||||||
SDValue
|
SDValue
|
||||||
MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
|
MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
|
||||||
CallingConv::ID CallConv,
|
CallingConv::ID CallConv,
|
||||||
@ -311,6 +317,7 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
|
|||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||||
|
MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
|
||||||
|
|
||||||
// Assign locations to all of the incoming arguments.
|
// Assign locations to all of the incoming arguments.
|
||||||
SmallVector<CCValAssign, 16> ArgLocs;
|
SmallVector<CCValAssign, 16> ArgLocs;
|
||||||
@ -318,7 +325,11 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
|
|||||||
getTargetMachine(), ArgLocs, *DAG.getContext());
|
getTargetMachine(), ArgLocs, *DAG.getContext());
|
||||||
CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
|
CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
|
||||||
|
|
||||||
assert(!isVarArg && "Varargs not supported yet");
|
// Create frame index for the start of the first vararg value
|
||||||
|
if (isVarArg) {
|
||||||
|
unsigned Offset = CCInfo.getNextStackOffset();
|
||||||
|
FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||||
CCValAssign &VA = ArgLocs[i];
|
CCValAssign &VA = ArgLocs[i];
|
||||||
@ -957,6 +968,22 @@ SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
|
|||||||
return FrameAddr;
|
return FrameAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
|
MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
|
||||||
|
|
||||||
|
// Frame index of first vararg argument
|
||||||
|
SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
|
||||||
|
getPointerTy());
|
||||||
|
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||||
|
|
||||||
|
// Create a store of the frame index to the location operand
|
||||||
|
return DAG.getStore(Op.getOperand(0), Op.getDebugLoc(), FrameIndex,
|
||||||
|
Op.getOperand(1), MachinePointerInfo(SV),
|
||||||
|
false, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/// getPostIndexedAddressParts - returns true by value, base pointer and
|
/// getPostIndexedAddressParts - returns true by value, base pointer and
|
||||||
/// offset pointer and addressing mode by reference if this node can be
|
/// offset pointer and addressing mode by reference if this node can be
|
||||||
/// combined with a load / store to form a post-indexed load / store.
|
/// combined with a load / store to form a post-indexed load / store.
|
||||||
|
@ -92,6 +92,7 @@ namespace llvm {
|
|||||||
SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const;
|
SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const;
|
||||||
|
|
||||||
TargetLowering::ConstraintType
|
TargetLowering::ConstraintType
|
||||||
|
@ -30,6 +30,9 @@ class MSP430MachineFunctionInfo : public MachineFunctionInfo {
|
|||||||
/// ReturnAddrIndex - FrameIndex for return slot.
|
/// ReturnAddrIndex - FrameIndex for return slot.
|
||||||
int ReturnAddrIndex;
|
int ReturnAddrIndex;
|
||||||
|
|
||||||
|
/// VarArgsFrameIndex - FrameIndex for start of varargs area.
|
||||||
|
int VarArgsFrameIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MSP430MachineFunctionInfo() : CalleeSavedFrameSize(0) {}
|
MSP430MachineFunctionInfo() : CalleeSavedFrameSize(0) {}
|
||||||
|
|
||||||
@ -41,6 +44,9 @@ public:
|
|||||||
|
|
||||||
int getRAIndex() const { return ReturnAddrIndex; }
|
int getRAIndex() const { return ReturnAddrIndex; }
|
||||||
void setRAIndex(int Index) { ReturnAddrIndex = Index; }
|
void setRAIndex(int Index) { ReturnAddrIndex = Index; }
|
||||||
|
|
||||||
|
int getVarArgsFrameIndex() const { return VarArgsFrameIndex;}
|
||||||
|
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
50
test/CodeGen/MSP430/vararg.ll
Normal file
50
test/CodeGen/MSP430/vararg.ll
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
; RUN: llc < %s | FileCheck %s
|
||||||
|
|
||||||
|
target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"
|
||||||
|
target triple = "msp430---elf"
|
||||||
|
|
||||||
|
declare void @llvm.va_start(i8*) nounwind
|
||||||
|
declare void @llvm.va_end(i8*) nounwind
|
||||||
|
declare void @llvm.va_copy(i8*, i8*) nounwind
|
||||||
|
|
||||||
|
define void @va_start(i16 %a, ...) nounwind {
|
||||||
|
entry:
|
||||||
|
; CHECK: va_start:
|
||||||
|
; CHECK: sub.w #2, r1
|
||||||
|
%vl = alloca i8*, align 2
|
||||||
|
%vl1 = bitcast i8** %vl to i8*
|
||||||
|
; CHECK-NEXT: mov.w r1, [[REG:r[0-9]+]]
|
||||||
|
; CHECK-NEXT: add.w #6, [[REG]]
|
||||||
|
; CHECK-NEXT: mov.w [[REG]], 0(r1)
|
||||||
|
call void @llvm.va_start(i8* %vl1)
|
||||||
|
call void @llvm.va_end(i8* %vl1)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define i16 @va_arg(i8* %vl) nounwind {
|
||||||
|
entry:
|
||||||
|
; CHECK: va_arg:
|
||||||
|
%vl.addr = alloca i8*, align 2
|
||||||
|
; CHECK: mov.w r15, 0(r1)
|
||||||
|
store i8* %vl, i8** %vl.addr, align 2
|
||||||
|
; CHECK: mov.w r15, [[REG:r[0-9]+]]
|
||||||
|
; CHECK-NEXT: add.w #2, [[REG]]
|
||||||
|
; CHECK-NEXT: mov.w [[REG]], 0(r1)
|
||||||
|
%0 = va_arg i8** %vl.addr, i16
|
||||||
|
; CHECK-NEXT: mov.w 0(r15), r15
|
||||||
|
ret i16 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @va_copy(i8* %vl) nounwind {
|
||||||
|
entry:
|
||||||
|
; CHECK: va_copy:
|
||||||
|
%vl.addr = alloca i8*, align 2
|
||||||
|
%vl2 = alloca i8*, align 2
|
||||||
|
; CHECK: mov.w r15, 2(r1)
|
||||||
|
store i8* %vl, i8** %vl.addr, align 2
|
||||||
|
%0 = bitcast i8** %vl2 to i8*
|
||||||
|
%1 = bitcast i8** %vl.addr to i8*
|
||||||
|
; CHECK-NEXT: mov.w r15, 0(r1)
|
||||||
|
call void @llvm.va_copy(i8* %0, i8* %1)
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user