diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_args.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_args.h index 67e6f402c70e847604218423a06a74735ec6575e..8e65824e2eee1276ab133276802c4d5c2b29d9df 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_args.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_args.h @@ -31,6 +31,8 @@ struct ArgInfo { const AArch64SymbolAlloc *symLoc; uint8 memPairSecondRegSize; /* struct arg requiring two regs, size of 2nd reg */ bool doMemPairOpt; + bool createTwoStores; + bool isTwoRegParm; }; class AArch64MoveRegArgs : public MoveRegArgs { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 722ac3d6750dfc17b5c8f41a89c42878e3046a9a..086b43773c59a8adbd082487aee92c969e529baf 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -89,7 +89,11 @@ ArgInfo AArch64MoveRegArgs::GetArgInfo(std::map &argsList, s argInfo.symSize = aarchCGFunc->GetBecommon().GetTypeSize(argInfo.mirTy->GetTypeIndex()); argInfo.memPairSecondRegSize = 0; argInfo.doMemPairOpt = false; + argInfo.createTwoStores = false; + argInfo.isTwoRegParm = false; + if ((argInfo.symSize > k8ByteSize) && (argInfo.symSize <= k16ByteSize)) { + argInfo.isTwoRegParm = true; if (numFpRegs[argIndex] > kOneRegister) { argInfo.symSize = argInfo.stkSize = fpSize[argIndex]; } else { @@ -109,6 +113,7 @@ ArgInfo AArch64MoveRegArgs::GetArgInfo(std::map &argsList, s /* For small aggregate parameter, set to minimum of 4 bytes. */ argInfo.symSize = argInfo.stkSize = k4ByteSize; } else if (numFpRegs[argIndex] > kOneRegister) { + argInfo.isTwoRegParm = true; argInfo.symSize = argInfo.stkSize = fpSize[argIndex]; } else { argInfo.stkSize = (argInfo.symSize < k4ByteSize) ? k4ByteSize : argInfo.symSize; @@ -128,6 +133,7 @@ ArgInfo AArch64MoveRegArgs::GetArgInfo(std::map &argsList, s */ argInfo.symSize = kSizeOfPtr; argInfo.doMemPairOpt = false; + argInfo.createTwoStores = true; } return argInfo; } @@ -254,7 +260,7 @@ void AArch64MoveRegArgs::GenerateStrInsn(ArgInfo &argInfo, AArch64reg reg2, uint } aarchCGFunc->GetCurBB()->AppendInsn(insn); - if (argInfo.doMemPairOpt) { + if (argInfo.createTwoStores || argInfo.doMemPairOpt) { /* second half of the struct passing by registers. */ uint32 part2BitSize = argInfo.memPairSecondRegSize * kBitsPerByte; GenOneInsn(argInfo, *baseOpnd, part2BitSize, reg2, (stOffset + kSizeOfPtr)); @@ -302,7 +308,9 @@ void AArch64MoveRegArgs::MoveRegisterArgs() { static_cast(aarchCGFunc->GetMemlayout()->GetSymAllocInfo( secondArgInfo.sym->GetStIndex())); /* Make sure they are in same segment if want to use stp */ - if (IsInSameSegment(firstArgInfo, secondArgInfo)) { + if (((firstArgInfo.isTwoRegParm && secondArgInfo.isTwoRegParm) || + (firstArgInfo.isTwoRegParm == false && secondArgInfo.isTwoRegParm == false)) && + (firstArgInfo.doMemPairOpt || IsInSameSegment(firstArgInfo, secondArgInfo))) { GenerateStpInsn(firstArgInfo, secondArgInfo); it = next; continue; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 2da54cb6254d30b5c9d65f020dce9f14741d40ef..d8ece10f073fb3d4d701bf0b2b2788425d28a9ff 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -206,6 +206,10 @@ void AArch64MemLayout::LayoutFormalParams() { SetSizeAlignForTypeIdx(ptyIdx, size, align); symLoc->SetMemSegment(GetSegArgsRegPassed()); /* the type's alignment requirement may be smaller than a registser's byte size */ + if (ty->GetPrimType() == PTY_agg && be.GetTypeSize(ptyIdx) > k4ByteSize) { + /* struct param aligned on 8 byte boundary unless it is small enough */ + align = kSizeOfPtr; + } segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), align)); symLoc->SetOffset(segArgsRegPassed.GetSize()); segArgsRegPassed.SetSize(segArgsRegPassed.GetSize() + size);