<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>