<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style id="owaParaStyle" type="text/css">P {margin-top:0;margin-bottom:0;}</style>
</head>
<body ocsi="0" fpstyle="1">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">Hi,<br>
<br>
Currently the XCore target passes the va_arg IR instruction to the back-end to handle<br>
- using the default DefaultABIInfo.<br>
However, this does mean that aggregate types are not handled.<br>
<br>
I assume to support aggregate types, I must lower them within clang.<br>
The question is should I:<br>
1. lower all types;<br>
2. just the aggregate types, passing all other types as var_arg instructions.<br>
<br>
On the surface, lowering all types does seem to allow better optimization - but may be this points to lack else where.<br>
<br>
Example code to to both (viz XCORE_USE_INST_VAR_ARG) is below & suitable patch+tests attached.<br>
Any comments on the correct way to handle var args welcome.<br>
Thank you<br>
<br>
Robert<br>
<br>
//#define XCORE_USE_INST_VAR_ARG<br>
llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,<br>
CodeGenFunction &CGF) const {<br>
ABIArgInfo AI = classifyArgumentType(Ty);<br>
<br>
#ifdef XCORE_USE_INST_VAR_ARG<br>
if (AI.getKind() != ABIArgInfo::Indirect)<br>
return 0; // use built in 'va_arg' instruction<br>
#endif<br>
<br>
CGBuilderTy &Builder = CGF.Builder;<br>
llvm::Type *ArgTy = CGT.ConvertType(Ty);<br>
if (AI.canHaveCoerceToType() && !AI.getCoerceToType())<br>
AI.setCoerceToType(ArgTy);<br>
<br>
// handle the VAList<br>
llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr,<br>
CGF.Int8PtrPtrTy, "ap");<br>
llvm::Value *AP = Builder.CreateLoad(VAListAddrAsBPP, "indirect");<br>
llvm::Value *APN = Builder.CreateConstGEP1_32(AP, 4, "ap.next");<br>
Builder.CreateStore(APN, VAListAddrAsBPP);<br>
<br>
// handle the argument<br>
llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy);<br>
#ifdef XCORE_USE_INST_VAR_ARG<br>
llvm::Value *ArgAddr;<br>
ArgAddr = Builder.CreateBitCast(AP, llvm::PointerType::getUnqual(ArgPtrTy),<br>
"indirect");<br>
ArgAddr = Builder.CreateLoad(ArgAddr, "arg");<br>
return Builder.CreatePointerCast(ArgAddr, ArgPtrTy, "arg");<br>
#else<br>
switch (AI.getKind()) {<br>
default:<br>
case ABIArgInfo::Expand:<br>
case ABIArgInfo::Extend:<br>
llvm_unreachable("Unsupported ABI kind for va_arg");<br>
case ABIArgInfo::Ignore:<br>
return llvm::UndefValue::get(ArgPtrTy);<br>
case ABIArgInfo::Direct:<br>
return Builder.CreatePointerCast(AP, ArgPtrTy, "arg");<br>
case ABIArgInfo::Indirect:<br>
llvm::Value *ArgAddr;<br>
ArgAddr = Builder.CreateBitCast(AP, llvm::PointerType::getUnqual(ArgPtrTy),<br>
"indirect");<br>
ArgAddr = Builder.CreateLoad(ArgAddr, "arg");<br>
return Builder.CreatePointerCast(ArgAddr, ArgPtrTy, "arg");<br>
}<br>
#endif<br>
}<br>
<br>
<br>
</div>
</body>
</html>