diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h index 84aca10943e6b83d3c61622976c98e65ddae1809..9740e68bf34d9fc9cf0a46654370919d23cfd6dc 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -109,7 +109,7 @@ class AArch64CGFunc : public CGFunc { void SelectComment(CommentNode &comment) override; void HandleCatch() override; - Operand *SelectDread(AddrofNode &expr) override; + Operand *SelectDread(const BaseNode &parent, AddrofNode &expr) override; RegOperand *SelectRegread(RegreadNode &expr) override; void SelectAddrof(Operand &result, StImmOperand &stImm); diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 00853febc8634f2c1b02248e5fba9f711226fe5a..f9f6479af9d5ae82affdcd5aa377c1826f9ad720 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -174,7 +174,7 @@ class CGFunc { virtual void HandleCatch() = 0; /* select expr */ - virtual Operand *SelectDread(AddrofNode &expr) = 0; + virtual Operand *SelectDread(const BaseNode &parent, AddrofNode &expr) = 0; virtual RegOperand *SelectRegread(RegreadNode &expr) = 0; virtual Operand *SelectAddrof(AddrofNode &expr) = 0; virtual Operand &SelectAddrofFunc(AddroffuncNode &expr) = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index 438542527109d09ef4a4b28334c1e0827d6fe916..4bc3e091950e4c0f33688b07699ae99e48e8ca32 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1304,7 +1304,7 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } -Operand *AArch64CGFunc::SelectDread(DreadNode &expr) { +Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)PTY_i32); @@ -1325,8 +1325,41 @@ Operand *AArch64CGFunc::SelectDread(DreadNode &expr) { parmCopy = IsParamStructCopy(*symbol); } CHECK_FATAL(symType != PTY_agg, "dread type error"); - uint32 dataSize = GetPrimTypeSize(symType) * kBitsPerByte; - MemOperand *memOpnd = nullptr; + uint32 dataSize = GetPrimTypeBitSize(symType); + uint32 aggSize = 0; + if (symType == PTY_agg) { + if (expr.GetPrimType() == PTY_agg) { + aggSize = GetBecommon().GetTypeSize(symbol->GetType()->GetTypeIndex().GetIdx()); + dataSize = k64BitSize; + } else { + dataSize = GetPrimTypeBitSize(expr.GetPrimType()); + } + } + MemOperand *memOpnd; + if (aggSize > k8ByteSize) { + if (parent.op == OP_eval) { + if (symbol->GetAttr(ATTR_volatile)) { + /* Need to generate loads for the upper parts of the struct. */ + Operand &dest = AArch64RegOperand::GetZeroRegister(k64BitSize); + uint32 numLoads = RoundUp(aggSize, k64BitSize) / k64BitSize; + for (uint32 o = 0; o < numLoads; ++o) { + if (parmCopy) { + memOpnd = &LoadStructCopyBase(*symbol, offset + o * kSizeOfPtr , kSizeOfPtr); + } else { + memOpnd = &GetOrCreateMemOpnd(*symbol, offset + o * kSizeOfPtr, kSizeOfPtr); + } + if (IsImmediateOffsetOutOfRange(*static_cast(memOpnd), kSizeOfPtr)) { + memOpnd = &SplitOffsetWithAddInstruction(*static_cast(memOpnd), kSizeOfPtr); + } + SelectCopy(dest, PTY_u64, *memOpnd, PTY_u64); + } + } else { + /* No side-effects. No need to generate anything for eval. */ + } + } else { + CHECK_FATAL(0,"SelectDread: Illegal agg size"); + } + } if (parmCopy) { memOpnd = &LoadStructCopyBase(*symbol, offset, dataSize); } else { @@ -1575,7 +1608,15 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr) { RegType regType = GetRegTyFromPrimTy(expr.GetPrimType()); uint32 regSize = GetPrimTypeSize(expr.GetPrimType()); - if (regSize < k4ByteSize) { + if (expr.GetFieldID() == 0 && pointedType->GetPrimType() == PTY_agg) { + /* Maple IR can passing small struct to be loaded into a single register. */ + if (regType == kRegTyFloat) { + /* regsize is correct */ + } else { + uint32 sz = GetBecommon().GetTypeSize(pointedType->GetTypeIndex().GetIdx()); + regSize = (sz <= 4) ? k4ByteSize : k8ByteSize; + } + } else if (regSize < k4ByteSize) { regSize = k4ByteSize; /* 32-bit */ } regno_t vRegNO; @@ -1607,6 +1648,27 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr) { } else { bitSize = GetPrimTypeBitSize(destType); } + if (regType == kRegTyFloat) { + destType = expr.GetPrimType(); + bitSize = GetPrimTypeBitSize(destType); + } else if (destType == PTY_agg) { + switch (bitSize) { + case k8BitSize: + destType = PTY_u8; + break; + case k16BitSize: + destType = PTY_u16; + break; + case k32BitSize: + destType = PTY_u32; + break; + case k64BitSize: + destType = PTY_u64; + break; + default: + CHECK_FATAL(false, "SelectIread: aggregate of wrong size"); + } + } } MemOperand *memOpnd = &CreateMemOpnd(destType, expr, *expr.Opnd(0), offset, memOrd); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index f7302199b8a7b42381e3fa3ae5708c8bfe13d3c0..3cf6279e5191a4786e8aedcbaf35ea7b4fd0b4b0 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -30,7 +30,7 @@ using namespace maple; Operand *HandleDread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) { (void)parent; auto &dreadNode = static_cast(expr); - return cgFunc.SelectDread(dreadNode); + return cgFunc.SelectDread(parent, dreadNode); } Operand *HandleRegread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) {