mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
PPC32 va_list is an actual structure so va_copy needs to copy the whole
structure not just a pointer. This implements that and thus fixes va_copy on PPC32. Fixes #15286. Both bug and patch by Florian Zeitz! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187158 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3367ed3220
commit
6ebf55d811
@ -280,8 +280,13 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
|
||||
} else
|
||||
setOperationAction(ISD::VAARG, MVT::Other, Expand);
|
||||
|
||||
if (Subtarget->isSVR4ABI() && !isPPC64)
|
||||
// VACOPY is custom lowered with the 32-bit SVR4 ABI.
|
||||
setOperationAction(ISD::VACOPY , MVT::Other, Custom);
|
||||
else
|
||||
setOperationAction(ISD::VACOPY , MVT::Other, Expand);
|
||||
|
||||
// Use the default implementation.
|
||||
setOperationAction(ISD::VACOPY , MVT::Other, Expand);
|
||||
setOperationAction(ISD::VAEND , MVT::Other, Expand);
|
||||
setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
|
||||
setOperationAction(ISD::STACKRESTORE , MVT::Other, Custom);
|
||||
@ -1650,6 +1655,18 @@ SDValue PPCTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG,
|
||||
false, false, false, 0);
|
||||
}
|
||||
|
||||
SDValue PPCTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG,
|
||||
const PPCSubtarget &Subtarget) const {
|
||||
assert(!Subtarget.isPPC64() && "LowerVACOPY is PPC32 only");
|
||||
|
||||
// We have to copy the entire va_list struct:
|
||||
// 2*sizeof(char) + 2 Byte alignment + 2*sizeof(char*) = 12 Byte
|
||||
return DAG.getMemcpy(Op.getOperand(0), Op,
|
||||
Op.getOperand(1), Op.getOperand(2),
|
||||
DAG.getConstant(12, MVT::i32), 8, false, true,
|
||||
MachinePointerInfo(), MachinePointerInfo());
|
||||
}
|
||||
|
||||
SDValue PPCTargetLowering::LowerADJUST_TRAMPOLINE(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
return Op.getOperand(0);
|
||||
@ -5715,6 +5732,9 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
case ISD::VAARG:
|
||||
return LowerVAARG(Op, DAG, PPCSubTarget);
|
||||
|
||||
case ISD::VACOPY:
|
||||
return LowerVACOPY(Op, DAG, PPCSubTarget);
|
||||
|
||||
case ISD::STACKRESTORE: return LowerSTACKRESTORE(Op, DAG, PPCSubTarget);
|
||||
case ISD::DYNAMIC_STACKALLOC:
|
||||
return LowerDYNAMIC_STACKALLOC(Op, DAG, PPCSubTarget);
|
||||
|
@ -498,6 +498,8 @@ namespace llvm {
|
||||
const PPCSubtarget &Subtarget) const;
|
||||
SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG,
|
||||
const PPCSubtarget &Subtarget) const;
|
||||
SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG,
|
||||
const PPCSubtarget &Subtarget) const;
|
||||
SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG,
|
||||
const PPCSubtarget &Subtarget) const;
|
||||
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG,
|
||||
|
24
test/CodeGen/PowerPC/ppc32-vacopy.ll
Normal file
24
test/CodeGen/PowerPC/ppc32-vacopy.ll
Normal file
@ -0,0 +1,24 @@
|
||||
; RUN: llc -mtriple="powerpc-unknown-linux-gnu" < %s | FileCheck %s
|
||||
; PR15286
|
||||
|
||||
%va_list = type {i8, i8, i16, i8*, i8*}
|
||||
declare void @llvm.va_copy(i8*, i8*)
|
||||
|
||||
define void @test_vacopy() nounwind {
|
||||
entry:
|
||||
%0 = alloca %va_list
|
||||
%1 = alloca %va_list
|
||||
%2 = bitcast %va_list* %0 to i8*
|
||||
%3 = bitcast %va_list* %1 to i8*
|
||||
|
||||
call void @llvm.va_copy(i8* %3, i8* %2)
|
||||
|
||||
ret void
|
||||
}
|
||||
; CHECK: test_vacopy:
|
||||
; CHECK: lwz [[REG1:[0-9]+]], {{.*}}
|
||||
; CHECK: lwz [[REG2:[0-9]+]], {{.*}}
|
||||
; CHECK: lwz [[REG3:[0-9]+]], {{.*}}
|
||||
; CHECK: stw [[REG1]], {{.*}}
|
||||
; CHECK: stw [[REG2]], {{.*}}
|
||||
; CHECK: stw [[REG3]], {{.*}}
|
Loading…
Reference in New Issue
Block a user