From 299c4150dd361beb060ae06b366c773f3453e584 Mon Sep 17 00:00:00 2001 From: William Chen Date: Mon, 25 Jan 2021 14:55:19 -0800 Subject: [PATCH 1/3] global assembly .comm should align with 8 bytes --- src/mapleall/maple_be/src/cg/emit.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 8d63b169f2..6a0b66054e 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -281,8 +281,13 @@ void Emitter::EmitAsmLabel(const MIRSymbol &mirSymbol, AsmLabel label) { emit(align); #else /* ELF */ /* output align, symbol name begin with "classInitProtectRegion" align is 4096 */ + MIRTypeKind kind = mirSymbol.GetType()->GetKind(); + MIRStorageClass storage = mirSymbol.GetStorageClass(); if (symName.find("classInitProtectRegion") == 0) { Emit(4096); + } else if ((kind == kTypeStruct || kind == kTypeClass || kind == kTypeArray || kind == kTypeUnion) && + (storage == kScGlobal || storage == kScPstatic || storage == kScFstatic)) { + Emit(std::to_string(k8ByteSize)); } else { Emit(std::to_string(Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirType->GetTypeIndex()))); } -- Gitee From 836e57ffd659fbe1eec11ef0290ac0aa6c62f934 Mon Sep 17 00:00:00 2001 From: William Chen Date: Mon, 25 Jan 2021 14:57:29 -0800 Subject: [PATCH 2/3] struct passed on stack should load data addr from stack --- .../src/cg/aarch64/aarch64_cgfunc.cpp | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) 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 0295789c58..e4b049dfb0 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -835,7 +835,7 @@ void AArch64CGFunc::SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPTyp Operand &stOpnd = LoadIntoRegister(opnd0, IsPrimitiveInteger(rhsPType), regSize, IsSignedInteger(type->GetPrimType())); MOperator mOp = MOP_undef; - if (type->GetKind() == kTypeStruct) { + if (type->GetKind() == kTypeStruct || type->GetKind() == kTypeUnion) { MIRStructType *structType = static_cast(type); type = structType->GetFieldType(fieldId); } else if (type->GetKind() == kTypeClass) { @@ -1421,6 +1421,33 @@ Operand *AArch64CGFunc::SelectAddrof(AddrofNode &expr) { ASSERT(structType != nullptr, "SelectAddrof: non-zero fieldID for non-structure"); offset = GetBecommon().GetFieldOffset(*structType, expr.GetFieldID()).first; } + if ((symbol->GetStorageClass() == kScFormal) && (symbol->GetSKind() == kStVar) && + ((expr.GetFieldID() != 0) || (GetBecommon().GetTypeSize(symbol->GetType()->GetTypeIndex().GetIdx()) > k16ByteSize))) { + // Struct param is copied on the stack by caller if struct size > 16. + // Else if size < 16 then struct param is copied into one or two registers. + RegOperand *stackAddr = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + // load the base address of the struct copy from stack. + SelectAddrof(*stackAddr, CreateStImmOperand(*symbol, 0, 0)); + Operand *structAddr; + if (GetBecommon().GetTypeSize(symbol->GetType()->GetTypeIndex().GetIdx()) <= k16ByteSize) { + structAddr = stackAddr; + } else { + AArch64OfstOperand *offopnd = &CreateOfstOpnd(0, 32); + AArch64MemOperand *mo = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, kSizeOfPtr * kBitsPerByte, + stackAddr, nullptr, offopnd, nullptr); + structAddr = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xldr, *structAddr, *mo)); + } + if (offset == 0) { + return structAddr; + } else { + // add the struct offset to the base address + Operand *result = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + ImmOperand *imm = &CreateImmOperand(PTY_a64, offset); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *result, *structAddr, *imm)); + return result; + } + } PrimType ptype = expr.GetPrimType(); regno_t vRegNO = NewVReg(kRegTyInt, GetPrimTypeSize(ptype)); Operand &result = CreateVirtualRegisterOperand(vRegNO); -- Gitee From b7b48ef2fdf7e4e3b7fc3f6f921c3a5c49187339 Mon Sep 17 00:00:00 2001 From: William Chen Date: Tue, 26 Jan 2021 14:36:31 -0800 Subject: [PATCH 3/3] Support small struct parameter with array access --- .../include/cg/aarch64/aarch64_cgfunc.h | 2 ++ src/mapleall/maple_be/include/cg/cgfunc.h | 2 ++ .../src/cg/aarch64/aarch64_cgfunc.cpp | 26 +++++++++++++++++++ src/mapleall/maple_be/src/cg/emit.cpp | 2 +- 4 files changed, 31 insertions(+), 1 deletion(-) 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 5d42f5200e..9f0c129fd1 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -272,6 +272,8 @@ class AArch64CGFunc : public CGFunc { return GetOrCreatePhysicalRegisterOperand(RFP, kSizeOfPtr * kBitsPerByte, kRegTyInt); } + RegOperand &GenStructParamIndex(RegOperand &base, BaseNode &indexExpr, int shift); + MemOperand &GetOrCreateMemOpnd(const MIRSymbol &symbol, int32 offset, uint32 size, bool forLocalRef = false); AArch64MemOperand &GetOrCreateMemOpnd(AArch64MemOperand::AArch64AddressingMode, uint32, RegOperand*, RegOperand*, diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 8845408f5c..cc74e6d8e3 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -819,8 +819,10 @@ class CGFunc { bool isVolLoad = false; bool isVolStore = false; bool isAfterRegAlloc = false; + bool isAggParamInReg = false; uint32 frequency = 0; DebugInfo *debugInfo = nullptr; /* debugging info */ + RegOperand *aggParamReg = nullptr; ReachingDefinition *reachingDef = nullptr; int32 dbgCallFrameOffset = 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 e4b049dfb0..718cfdb119 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1430,6 +1430,7 @@ Operand *AArch64CGFunc::SelectAddrof(AddrofNode &expr) { SelectAddrof(*stackAddr, CreateStImmOperand(*symbol, 0, 0)); Operand *structAddr; if (GetBecommon().GetTypeSize(symbol->GetType()->GetTypeIndex().GetIdx()) <= k16ByteSize) { + isAggParamInReg = true; structAddr = stackAddr; } else { AArch64OfstOperand *offopnd = &CreateOfstOpnd(0, 32); @@ -1553,6 +1554,10 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr) { } MemOperand *memOpnd = &CreateMemOpnd(destType, expr, *expr.Opnd(0), offset, memOrd); + if (aggParamReg) { + isAggParamInReg = false; + return aggParamReg; + } if (isVolLoad && (static_cast(memOpnd)->GetAddrMode() == AArch64MemOperand::kAddrModeBOi)) { memOrd = AArch64isa::kMoAcquire; isVolLoad = false; @@ -5510,6 +5515,22 @@ MemOperand &AArch64CGFunc::CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uin return *memPool->New(AArch64MemOperand::kAddrModeBOi, size, baseOpnd, nullptr, &offsetOpnd, &sym); } +RegOperand &AArch64CGFunc::GenStructParamIndex(RegOperand &base, BaseNode &indexExpr, int shift) { + RegOperand *index = &LoadIntoRegister(*HandleExpr(indexExpr, *(indexExpr.Opnd(0))), PTY_a64); + RegOperand *srcOpnd = &CreateRegisterOperandOfType(PTY_a64); + ImmOperand *imm = &CreateImmOperand(PTY_a64, shift); + SelectShift(*srcOpnd, *index, *imm, kShiftLeft, PTY_a64); + RegOperand *result = &CreateRegisterOperandOfType(PTY_a64); + SelectAdd(*result, base, *srcOpnd, PTY_a64); + + AArch64OfstOperand *offopnd = &CreateOfstOpnd(0, 32); + AArch64MemOperand &mo = GetOrCreateMemOpnd( AArch64MemOperand::kAddrModeBOi, k64BitSize, result, nullptr, offopnd, nullptr); + RegOperand &structAddr = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + GetCurBB()->AppendInsn(cg->BuildInstruction(MOP_xldr, structAddr, mo)); + + return structAddr; +} + /* iread a64 <* <* void>> 0 (add a64 ( * addrof a64 $__reg_jni_func_tab$$libcore_all_dex, * mul a64 ( @@ -5518,6 +5539,7 @@ MemOperand &AArch64CGFunc::CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uin */ MemOperand *AArch64CGFunc::CheckAndCreateExtendMemOpnd(PrimType ptype, BaseNode &addrExpr, int32 offset, AArch64isa::MemoryOrdering memOrd) { + aggParamReg = nullptr; if (memOrd != AArch64isa::kMoNone || !IsPrimitiveInteger(ptype) || addrExpr.GetOpCode() != OP_add || offset != 0) { return nullptr; } @@ -5550,6 +5572,10 @@ MemOperand *AArch64CGFunc::CheckAndCreateExtendMemOpnd(PrimType ptype, BaseNode TypeCvtNode *typeCvtNode = static_cast(indexExpr); PrimType fromType = typeCvtNode->FromType(); PrimType toType = typeCvtNode->GetPrimType(); + if (isAggParamInReg) { + aggParamReg = &GenStructParamIndex(base, *indexExpr, shift); + return nullptr; + } MemOperand *memOpnd = nullptr; if ((fromType == PTY_i32) && (toType == PTY_a64)) { RegOperand &index = diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 6a0b66054e..5851d677c4 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] 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. -- Gitee