diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index 729738c96818833dc28736dc5c62901bb6e8418b..f21114e732664efe17f2d794e0ce89187360c0ba 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index 7a2bf855da407b622c3ff660e832dbbd5ee3a1a0..662d4069d0829a7c2022d51cf2fa7c1e9dc04493 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_be/include/be/common_utils.h b/src/mapleall/maple_be/include/be/common_utils.h index 2307a9f01631864a38c77aec4a759e94392288a0..96a785eade3466f97c41ecf713f7e0601369c2fd 100644 --- a/src/mapleall/maple_be/include/be/common_utils.h +++ b/src/mapleall/maple_be/include/be/common_utils.h @@ -32,6 +32,7 @@ constexpr uint32 kBaseOffsetAlignment = 3; constexpr uint32 k1FConst = 31; constexpr uint32 k0BitSize = 0; constexpr uint32 k1BitSize = 1; +constexpr uint32 k2BitSize = 2; constexpr uint32 k4BitSize = 4; constexpr uint32 k6BitSize = 6; constexpr uint32 k8BitSize = 8; @@ -125,6 +126,7 @@ constexpr int32 kMaxPimm32 = 16380; constexpr int32 kMaxPimm64 = 32760; constexpr int32 kMaxPimm[k4BitSize] = {kMaxPimm8, kMaxPimm16, kMaxPimm32, kMaxPimm64}; +constexpr int32 kMaxPairPimm[k2BitSize] = {k256BitSize, k512BitSize}; constexpr int32 kMax12UnsignedImm = 4096; constexpr int32 kMax13UnsignedImm = 8192; 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 d611692293a3e0dec09e997df30750b281f2c85d..c7bd42c6007f423b6398723115aad1515db3a289 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -94,6 +94,7 @@ class AArch64CGFunc : public CGFunc { void SelectAsm(AsmNode &stmt) override; AArch64MemOperand *GenLargeAggFormalMemOpnd(const MIRSymbol &sym, uint32 alignUsed, int32 offset); AArch64MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); + AArch64MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; @@ -129,6 +130,7 @@ class AArch64CGFunc : public CGFunc { Operand *SelectIread(const BaseNode &parent, IreadNode &expr) override; Operand *SelectIntConst(MIRIntConst &intConst) override; + Operand *HandleFmovImm(PrimType stype, int64 val); Operand *SelectFloatConst(MIRFloatConst &floatConst) override; Operand *SelectDoubleConst(MIRDoubleConst &doubleConst) override; Operand *SelectStrConst(MIRStrConst &strConst) override; @@ -137,6 +139,8 @@ class AArch64CGFunc : public CGFunc { void SelectAdd(Operand &resOpnd, Operand &o0, Operand &o1, PrimType primType) override; Operand *SelectAdd(BinaryNode &node, Operand &o0, Operand &o1, const BaseNode &parent) override; Operand &SelectCGArrayElemAdd(BinaryNode &node) override; + void SelectMadd(Operand &resOpnd, Operand &oM0, Operand &oM1, Operand &o1, PrimType primeType) override; + Operand *SelectMadd(BinaryNode &node, Operand &oM0, Operand &oM1, Operand &o1) override; Operand *SelectShift(BinaryNode &node, Operand &o0, Operand &o1) override; Operand *SelectSub(BinaryNode &node, Operand &o0, Operand &o1) override; void SelectSub(Operand &resOpnd, Operand &o0, Operand &o1, PrimType primType) override; @@ -467,9 +471,10 @@ class AArch64CGFunc : public CGFunc { bool CheckIfSplitOffsetWithAdd(const AArch64MemOperand &memOpnd, uint32 bitLen); RegOperand *GetBaseRegForSplit(uint32 baseRegNum); + AArch64MemOperand &SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, uint32 baseRegNum = AArch64reg::kRinvalid, bool isDest = false, - Insn *insn = nullptr); + Insn *insn = nullptr, bool forPair = false); AArch64MemOperand &CreateReplacementMemOperand(uint32 bitLen, RegOperand &baseReg, int32 offset); bool HasStackLoadStore(); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index 236c987922bef3218ce4f30f4732af27cdbaef8c..d8f095ca4886228ed799fdfd35d54185ba7a452e 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1094,12 +1094,12 @@ class GraphColorRegAllocator : public AArch64RegAllocator { fpSpillRegSet(alloc.Adapter()), intCalleeUsed(alloc.Adapter()), fpCalleeUsed(alloc.Adapter()) { - constexpr uint32 kNumInsnThreashold = 200000; + constexpr uint32 kNumInsnThreashold = 30000; numVregs = cgFunc.GetMaxVReg(); lrVec.resize(numVregs); localRegVec.resize(cgFunc.NumBBs()); bbRegInfo.resize(cgFunc.NumBBs()); - if (CGOptions::DoMultiPassColorRA()) { + if (CGOptions::DoMultiPassColorRA() && cgFunc.GetMirModule().IsCModule()) { uint32 cnt = 0; FOR_ALL_BB(bb, &cgFunc) { FOR_BB_INSNS(insn, bb) { diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h index f8345412d5f5db257a30e61fc999beaf96d77c5a..2d692ed604e3fd4c4e4fa1ba383ad12bdea3b6f4 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h @@ -196,8 +196,8 @@ struct VectorRegSpec { class AArch64VectorInsn : public AArch64Insn { public: AArch64VectorInsn(MemPool &memPool, MOperator opc) - : AArch64Insn(memPool, opc), - regSpecList(localAlloc.Adapter()) { + : AArch64Insn(memPool, opc), + regSpecList(localAlloc.Adapter()) { regSpecList.clear(); } @@ -208,7 +208,6 @@ class AArch64VectorInsn : public AArch64Insn { } VectorRegSpec *GetAndRemoveRegSpecFromList() { - //ASSERT(regSpecList.size() > 0, "regSpecList empty"); if (regSpecList.size() == 0) { VectorRegSpec *vecSpec = CG::GetCurCGFuncNoConst()->GetMemoryPool()->New(); return vecSpec; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def index beda9238b7e1b686e3caedeb0c6744fb541224af..d59bc31bc6b0e9b9ca4b5d9b39a017d024c31ff2 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def @@ -126,6 +126,12 @@ DEFINE_MOP(MOP_xvmuld, {mopdReg64FD,mopdReg64FS,mopdReg64FS},0,kLtFpmul,"fmul"," /*MOP_xsmullrrr */ DEFINE_MOP(MOP_xsmullrrr, {mopdReg64ID,mopdReg32IS,mopdReg32IS},0,kLtMul,"smull","0,1,2",1) +/* AARCH64 Arithmetic: multiply first then add */ +/* MOP_xmaddrrrr */ +DEFINE_MOP(MOP_xmaddrrrr, {mopdReg64ID,mopdReg64IS,mopdReg64IS,mopdReg64IS},0,kLtMul,"madd","0,1,2,3",1) +/* MOP_wmaddrrrr */ +DEFINE_MOP(MOP_wmaddrrrr, {mopdReg32ID,mopdReg32IS,mopdReg32IS,mopdReg32IS},0,kLtMul,"madd","0,1,2,3",1) + /* AARCH64 leading zeros, reverse bits (for trailing zeros) */ /* MOP_wclz */ DEFINE_MOP(MOP_wclz, {mopdReg32ID,mopdReg32IS},0,kLtAlu,"clz","0,1", 1) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h index f964e99a69ea9ea90ecf6fbbcafc2708c53e5b4c..d68f455534ad70fbed2705a20b713369a0206052 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h @@ -105,7 +105,6 @@ class AArch64RegOperand : public RegOperand { return vecLaneSize; } - bool operator==(const AArch64RegOperand &opnd) const; bool operator<(const AArch64RegOperand &opnd) const; @@ -703,7 +702,18 @@ class AArch64MemOperand : public MemOperand { /* alignment is between kAlignmentOf8Bit and kAlignmentOf64Bit */ ASSERT(alignment >= kOffsetAlignmentOf8Bit, "error val:alignment"); ASSERT(alignment <= kOffsetAlignmentOf64Bit, "error val:alignment"); - return (kMaxPimms[alignment]); + return (kMaxPimm[alignment]); + } + + static int32 GetMaxPairPIMM(uint32 dSize) { + ASSERT(dSize >= k32BitSize, "error val:dSize"); + ASSERT(dSize <= k64BitSize, "error val:dSize"); + ASSERT((dSize & (dSize - 1)) == 0, "error val:dSize"); + int32 alignment = GetImmediateOffsetAlignment(dSize); + /* alignment is between kAlignmentOf8Bit and kAlignmentOf64Bit */ + ASSERT(alignment >= kOffsetAlignmentOf32Bit, "error val:alignment"); + ASSERT(alignment <= kOffsetAlignmentOf64Bit, "error val:alignment"); + return (kMaxPairPimm[alignment - k2BitSize]); } bool IsOffsetMisaligned(uint32 dSize) const { @@ -837,8 +847,6 @@ class AArch64MemOperand : public MemOperand { static constexpr int32 kLdpStp64SimmLowerBound = -512; /* multiple of 8 */ static constexpr int32 kLdpStp64SimmUpperBound = 504; - static const int32 kMaxPimms[4]; - AArch64AddressingMode addrMode; uint32 extend; /* used with offset register ; AddrMode_B_OR_X */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 3d6a81f954b079df5857d0aa3e546a61f9b229bb..34f6a822c2ddcedeb023c7f451a6c1eb1db83769 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -202,6 +202,8 @@ class CGFunc { virtual Operand *SelectStr16Const(MIRStr16Const &strConst) = 0; virtual void SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0; virtual Operand *SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; + virtual void SelectMadd(Operand &resOpnd, Operand &opndM0, Operand &opndM1, Operand &opnd1, PrimType primType) = 0; + virtual Operand *SelectMadd(BinaryNode &node, Operand &opndM0, Operand &opndM1, Operand &opnd1) = 0; virtual Operand &SelectCGArrayElemAdd(BinaryNode &node) = 0; virtual Operand *SelectShift(BinaryNode &node, Operand &opnd0, Operand &opnd1) = 0; virtual void SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0; diff --git a/src/mapleall/maple_be/include/cg/dbg.def b/src/mapleall/maple_be/include/cg/dbg.def index 0fb910b44c73b63853e794ac7bcc924e94901916..9c8a9fa94fa6355a61369f7c96d20631f642a644 100644 --- a/src/mapleall/maple_be/include/cg/dbg.def +++ b/src/mapleall/maple_be/include/cg/dbg.def @@ -1,17 +1,16 @@ /* * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: * - * https://opensource.org/licenses/MulanPSL-2.0 + * http://license.coscl.org.cn/MulanPSL * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR * FIT FOR A PARTICULAR PURPOSE. - * See the MulanPSL - 2.0 for more details. + * See the Mulan PSL v1 for more details. */ - -// .loc filenum linenum +/* .loc fileNum lineNum */ DBG_DEFINE(loc, , 2, Immediate, Immediate, Undef) diff --git a/src/mapleall/maple_be/include/cg/dbg.h b/src/mapleall/maple_be/include/cg/dbg.h index 34a19fe724cd043dfd8442211f058bfab52e5fb5..afac7536fa50160ee6bf89ec0b5cfc81a0c677da 100644 --- a/src/mapleall/maple_be/include/cg/dbg.h +++ b/src/mapleall/maple_be/include/cg/dbg.h @@ -23,7 +23,7 @@ namespace mpldbg { using namespace maple; -// https://sourceware.org/binutils/docs-2.28/as/Loc.html +/* https://sourceware.org/binutils/docs-2.28/as/Loc.html */ enum LocOpt { kBB, kProEnd, kEpiBeg, kIsStmt, kIsa, kDisc }; enum DbgOpcode : uint8 { diff --git a/src/mapleall/maple_be/src/be/becommon.cpp b/src/mapleall/maple_be/src/be/becommon.cpp index a3ca37041078dae5e703a13d01edbd1c78305d8e..ae8e329ab73b93e933a0eb45ddccc0ace4acaeb7 100644 --- a/src/mapleall/maple_be/src/be/becommon.cpp +++ b/src/mapleall/maple_be/src/be/becommon.cpp @@ -569,8 +569,18 @@ std::pair BECommon::GetFieldOffset(MIRStructType &structType, Fiel if (structType.GetKind() != kTypeUnion) { if (fieldType->GetKind() == kTypeBitField) { uint32 fieldSize = static_cast(fieldType)->GetFieldSize(); - /* is this field is crossing the align boundary of its base type? */ - if ((allocedSizeInBits / (fieldAlign * 8u)) != ((allocedSizeInBits + fieldSize - 1u) / (fieldAlign * 8u))) { + /* + * Is this field is crossing the align boundary of its base type? Or, + * is field a zero-with bit field? + * Refer to C99 standard (ยง6.7.2.1) : + * > As a special case, a bit-field structure member with a width of 0 indicates that no further + * > bit-field is to be packed into the unit in which the previous bit-field, if any, was placed. + * + * We know that A zero-width bit field can cause the next field to be aligned on the next container + * boundary where the container is the same size as the underlying type of the bit field. + */ + if (((allocedSizeInBits / (fieldAlign * 8u)) != ((allocedSizeInBits + fieldSize - 1u) / (fieldAlign * 8u))) || + fieldSize == 0) { /* * the field is crossing the align boundary of its base type; * align alloced_size_in_bits to fieldAlign @@ -581,13 +591,6 @@ std::pair BECommon::GetFieldOffset(MIRStructType &structType, Fiel if (curFieldID == fieldID) { return std::pair((allocedSizeInBits / (fieldAlign * 8u)) * fieldAlign, allocedSizeInBits % (fieldAlign * 8u)); - } else if (fieldType->GetKind() == kTypeStruct) { - if ((curFieldID + GetStructFieldCount(fieldTyIdx)) >= fieldID) { - MIRStructType *subStructType = static_cast(fieldType); - std::pair result = GetFieldOffset(*subStructType, fieldID - curFieldID); - return std::pair(result.first + allocedSize, result.second); - } - curFieldID += GetStructFieldCount(fieldTyIdx) + 1; } else { ++curFieldID; } 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 ad7b872f4b83539001719c5bc0ea936fda4d0b10..8a6b38f5e9c5199cd814b7c98704d3ff609e377c 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -717,7 +717,8 @@ void AArch64CGFunc::SelectCopy(Operand &dest, PrimType dtype, Operand &src, Prim vecSpecSrc->vecLaneMax = k16BitSize; VectorRegSpec *vecSpecDest = GetMemoryPool()->New(); vecSpecDest->vecLaneMax = k16BitSize; - Insn *insn = &GetCG()->BuildInstruction(dsize <= k64BitSize ? MOP_vmovuu : MOP_vmovvv, dest, src); + Insn *insn = + &GetCG()->BuildInstruction(dsize <= k64BitSize ? MOP_vmovuu : MOP_vmovvv, dest, src); static_cast(insn)->PushRegSpecEntry(vecSpecDest); static_cast(insn)->PushRegSpecEntry(vecSpecSrc); GetCurBB()->AppendInsn(*insn); @@ -835,7 +836,8 @@ RegOperand *AArch64CGFunc::GetBaseRegForSplit(uint32 baseRegNum) { } AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, - uint32 baseRegNum, bool isDest, Insn *insn) { + uint32 baseRegNum, bool isDest, + Insn *insn, bool forPair) { ASSERT((memOpnd.GetAddrMode() == AArch64MemOperand::kAddrModeBOi), "expect kAddrModeBOi memOpnd"); ASSERT(memOpnd.IsIntactIndexed(), "expect intactIndexed memOpnd"); AArch64OfstOperand *ofstOpnd = memOpnd.GetOffsetImmediate(); @@ -854,9 +856,20 @@ AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64Mem * ADD TEMP_REG, X29, ADDEND * LDR/STR TEMP_REG, [ TEMP_REG, #NEW_OFFSET ] */ - int32 maxPimm = memOpnd.GetMaxPIMM(bitLen); + int32 maxPimm = 0; + if (!forPair) { + maxPimm = memOpnd.GetMaxPIMM(bitLen); + } else { + maxPimm = memOpnd.GetMaxPairPIMM(bitLen); + } + ASSERT(maxPimm != 0, "get max pimm failed"); + + bool misAlignment = false; int32 q0 = opndVal / maxPimm; int32 addend = q0 * maxPimm; + if (addend == 0) { + misAlignment = true; + } int32 r0 = opndVal - addend; int32 alignment = memOpnd.GetImmediateOffsetAlignment(bitLen); int32 q1 = static_cast(r0) >> static_cast(alignment); @@ -864,15 +877,43 @@ AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64Mem addend = addend + r1; RegOperand *origBaseReg = memOpnd.GetBaseRegister(); ASSERT(origBaseReg != nullptr, "nullptr check"); + + if (misAlignment && addend != 0) { + ImmOperand &immAddend = CreateImmOperand(static_cast(q1) << static_cast(alignment), k64BitSize, true); + if (memOpnd.GetOffsetImmediate()->GetVary() == kUnAdjustVary) { + immAddend.SetVary(kUnAdjustVary); + } + RegOperand *resOpnd = GetBaseRegForSplit(baseRegNum); + if (insn == nullptr) { + SelectAdd(*resOpnd, *origBaseReg, immAddend, PTY_i64); + } else { + SelectAddAfterInsn(*resOpnd, *origBaseReg, immAddend, PTY_i64, isDest, *insn); + } + AArch64MemOperand &newMemOpnd = CreateReplacementMemOperand(bitLen, *resOpnd, r1); + newMemOpnd.SetStackMem(memOpnd.IsStackMem()); + return newMemOpnd; + } + if (addend > 0) { int32 t = addend; - constexpr uint32 suffixClear = 0xfffff000; + uint32 suffixClear = 0xfffff000; + if (forPair) { + suffixClear = 0xffffff00; + } addend = (static_cast(addend) & suffixClear); q1 = (static_cast(q1) << static_cast(alignment)) + (t - addend); - if (AArch64MemOperand::IsPIMMOffsetOutOfRange(q1, bitLen)) { - addend = (static_cast(opndVal) & suffixClear); - q1 = opndVal - addend; + if (!forPair) { + if (AArch64MemOperand::IsPIMMOffsetOutOfRange(q1, bitLen)) { + addend = (static_cast(opndVal) & suffixClear); + q1 = opndVal - addend; + } + } else { + if (q1 < 0 || q1 > maxPimm) { + addend = (static_cast(opndVal) & suffixClear); + q1 = opndVal - addend; + } } + ImmOperand &immAddend = CreateImmOperand(addend, k64BitSize, true); if (memOpnd.GetOffsetImmediate()->GetVary() == kUnAdjustVary) { immAddend.SetVary(kUnAdjustVary); @@ -1030,6 +1071,7 @@ void AArch64CGFunc::SelectAssertNull(UnaryStmtNode &stmt) { } void AArch64CGFunc::SelectAsm(AsmNode &node) { + (void)node; return; } @@ -1072,6 +1114,21 @@ AArch64MemOperand *AArch64CGFunc::FixLargeMemOpnd(MemOperand &memOpnd, uint32 al return lhsMemOpnd; } +AArch64MemOperand *AArch64CGFunc::FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx) { + auto *a64MemOpnd = static_cast(&memOpnd); + if ((a64MemOpnd->GetMemVaryType() == kNotVary) && !IsOperandImmValid(mOp, &memOpnd, opndIdx)) { + if (opndIdx == kInsnSecondOpnd) { + a64MemOpnd = &SplitOffsetWithAddInstruction(*a64MemOpnd, dSize); + } else if (opndIdx == kInsnThirdOpnd) { + a64MemOpnd = &SplitOffsetWithAddInstruction( + *a64MemOpnd, dSize, AArch64reg::kRinvalid, false, nullptr, true); + } else { + CHECK_FATAL(false, "NYI"); + } + } + return a64MemOpnd; +} + AArch64MemOperand *AArch64CGFunc::GenLargeAggFormalMemOpnd(const MIRSymbol &sym, uint32 align, int32 offset) { MemOperand *memOpnd; if (sym.GetStorageClass() == kScFormal && GetBecommon().GetTypeSize(sym.GetTyIdx()) > k16ByteSize) { @@ -1176,7 +1233,7 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { if (doPair) { AArch64OfstOperand &lhsOfstOpnd1 = GetOrCreateOfstOpnd(lhsBaseOffset + copySize, k32BitSize); MemOperand *lhsMemOpnd1 = - &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); lhsMemOpnd1 = FixLargeMemOpnd(*lhsMemOpnd1, copySize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, *result1, *lhsMemOpnd1)); } @@ -1282,7 +1339,7 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { if (doPair) { AArch64OfstOperand &lhsOfstOpnd1 = GetOrCreateOfstOpnd(lhsBaseOffset + copySize, k32BitSize); MemOperand *lhsMemOpnd1 = - &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); lhsMemOpnd1 = FixLargeMemOpnd(*lhsMemOpnd1, copySize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, *result1, *lhsMemOpnd1)); } @@ -1607,15 +1664,16 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { /* generate the load */ RegOperand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); MOperator mOpLDP = (copySize == k4BitSize) ? MOP_wldp : MOP_xldp; - bool isInRange = IsOperandImmValid(mOpLDP, rhsMemOpnd, kInsnThirdOpnd); - bool doPair = (!rhsIsLo12 && (copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && isInRange); + bool doPair = (!rhsIsLo12 && (copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize))); RegOperand *result1 = nullptr; if (doPair) { regno_t vRegNO1 = NewVReg(kRegTyInt, std::max(4u, copySize)); result1 = &CreateVirtualRegisterOperand(vRegNO1); + rhsMemOpnd = FixLargeMemOpnd(mOpLDP, *static_cast(rhsMemOpnd), result.GetSize(), kInsnThirdOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd)); } else { MOperator mOp = PickLdInsn(copySize * k8BitSize, PTY_u32); + rhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(rhsMemOpnd), result.GetSize(), kInsnSecondOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd)); } /* generate the store */ @@ -1624,10 +1682,12 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { static_cast(&lhsAddrOpnd), nullptr, &ofstOpnd, nullptr); if (doPair) { MOperator mOpSTP = (copySize == k4BitSize) ? MOP_wstp : MOP_xstp; + lhsMemOpnd = FixLargeMemOpnd(mOpSTP, *static_cast(lhsMemOpnd), result.GetSize(), kInsnThirdOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(copySize * k8BitSize, PTY_u32); + lhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(lhsMemOpnd), copySize * k8BitSize, kInsnSecondOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *lhsMemOpnd)); } } @@ -1718,19 +1778,18 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(rhsOffset + i * copySize, k32BitSize); Operand *rhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, operandSize, static_cast(rhsAddrOpnd), nullptr, &rhsOfstOpnd, nullptr); - bool isInRange = IsOperandImmValid(mOpLDP, rhsMemOpnd, kInsnThirdOpnd); - if (!isInRange) { - rhsMemOpnd = &SplitOffsetWithAddInstruction(*static_cast(rhsMemOpnd), operandSize); - } + RegOperand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); - bool doPair = ((copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && isInRange); + bool doPair = ((copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize))); Insn *insn = nullptr; RegOperand *result1 = nullptr; if (doPair) { + rhsMemOpnd = FixLargeMemOpnd(mOpLDP, *static_cast(rhsMemOpnd), operandSize, kInsnThirdOpnd); result1 = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); insn = &GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd); } else { MOperator mOp = PickLdInsn(operandSize, PTY_u32); + rhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(rhsMemOpnd), operandSize, kInsnSecondOpnd); insn = &GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd); } insn->MarkAsAccessRefField(isRefField); @@ -1740,15 +1799,13 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { AArch64OfstOperand &lhsOfstOpnd = GetOrCreateOfstOpnd(lhsOffset + i * copySize, k32BitSize); Operand *lhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, operandSize, static_cast(&lhsAddrOpnd), nullptr, &lhsOfstOpnd, nullptr); - isInRange = IsOperandImmValid(mOpSTP, lhsMemOpnd, kInsnThirdOpnd); - if (!isInRange) { - lhsMemOpnd = &SplitOffsetWithAddInstruction(*static_cast(lhsMemOpnd), operandSize); - } if (doPair) { + lhsMemOpnd = FixLargeMemOpnd(mOpSTP, *static_cast(lhsMemOpnd), operandSize, kInsnThirdOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(operandSize, PTY_u32); + lhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(lhsMemOpnd), operandSize, kInsnSecondOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *lhsMemOpnd)); } } @@ -2251,17 +2308,51 @@ Operand *SelectLiteral(T *c, MIRFunction *func, uint32 labelIdx, AArch64CGFunc * return nullptr; } +Operand *AArch64CGFunc::HandleFmovImm(PrimType stype, int64 val) { + Operand *result; + bool is64Bits = (GetPrimTypeBitSize(stype) == k64BitSize); + uint64 canRepreset = is64Bits ? (val & 0xffffffffffff) : (val & 0x7ffff); + uint32 val1 = is64Bits ? (val >> 61) & 0x3 : (val >> 29) & 0x3; + uint32 val2 = is64Bits ? (val >> 54) & 0xff : (val >> 25) & 0x1f; + bool isSame = is64Bits ? ((val2 == 0) || (val2 == 0xff)) : ((val2 == 0) || (val2 == 0x1f)); + canRepreset = (canRepreset == 0) && ((val1 & 0x1) ^ ((val1 & 0x2) >> 1)) && isSame; + if (canRepreset) { + uint64 temp1 = is64Bits ? (val >> 63) << 7 : (val >> 31) << 7; + uint64 temp2 = is64Bits ? val >> 48 : val >> 19; + int64 imm8 = (temp2 & 0x7f) | temp1; + Operand *newOpnd0 = &CreateImmOperand(imm8, k8BitSize, true, kNotVary, true); + regno_t vRegNO = NewVReg(kRegTyFloat, GetPrimTypeSize(stype)); + result = &CreateVirtualRegisterOperand(vRegNO); + MOperator mopFmov = (is64Bits ? MOP_xdfmovri : MOP_wsfmovri); + GetCurBB()->AppendInsn(cg->BuildInstruction(mopFmov, *result, *newOpnd0)); + } else { + Operand *newOpnd0 = &CreateImmOperand(val, GetPrimTypeSize(stype) * kBitsPerByte, false); + PrimType itype = (stype == PTY_f32) ? PTY_i32 : PTY_i64; + RegOperand ®Opnd = LoadIntoRegister(*newOpnd0, itype); + + regno_t vRegNO = NewVReg(kRegTyFloat, GetPrimTypeSize(stype)); + result = &CreateVirtualRegisterOperand(vRegNO); + MOperator mopFmov = (is64Bits ? MOP_xvmovdr: MOP_xvmovsr); + GetCurBB()->AppendInsn(cg->BuildInstruction(mopFmov, *result, regOpnd)); + } + return result; +} + Operand *AArch64CGFunc::SelectFloatConst(MIRFloatConst &floatConst) { - uint32 labelIdxTmp = GetLabelIdx(); - Operand *result = SelectLiteral(&floatConst, &GetFunction(), labelIdxTmp++, this); - SetLabelIdx(labelIdxTmp); + PrimType stype = floatConst.GetType().GetPrimType(); + int32 val = floatConst.GetIntValue(); + /* according to aarch64 encoding format, convert int to float expression */ + Operand *result = HandleFmovImm(stype, val); + return result; } Operand *AArch64CGFunc::SelectDoubleConst(MIRDoubleConst &doubleConst) { - uint32 labelIdxTmp = GetLabelIdx(); - Operand *result = SelectLiteral(&doubleConst, &GetFunction(), labelIdxTmp++, this); - SetLabelIdx(labelIdxTmp); + PrimType stype = doubleConst.GetType().GetPrimType(); + int64 val = doubleConst.GetIntValue(); + /* according to aarch64 encoding format, convert int to float expression */ + Operand *result = HandleFmovImm(stype, val); + return result; } @@ -2728,6 +2819,42 @@ void AArch64CGFunc::SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, } } +Operand *AArch64CGFunc::SelectMadd(BinaryNode &node, Operand &opndM0, Operand &opndM1, Operand &opnd1) { + PrimType dtype = node.GetPrimType(); + bool isSigned = IsSignedInteger(dtype); + uint32 dsize = GetPrimTypeBitSize(dtype); + bool is64Bits = (dsize == k64BitSize); + /* promoted type */ + PrimType primType = is64Bits ? (isSigned ? PTY_i64 : PTY_u64) : (isSigned ? PTY_i32 : PTY_u32); + RegOperand &resOpnd = CreateRegisterOperandOfType(primType); + + SelectMadd(resOpnd, opndM0, opndM1, opnd1, primType); + return &resOpnd; +} + +void AArch64CGFunc::SelectMadd(Operand &resOpnd, Operand &opndM0, Operand &opndM1, Operand &opnd1, PrimType primType) { + Operand::OperandType opndM0Type = opndM0.GetKind(); + Operand::OperandType opndM1Type = opndM1.GetKind(); + Operand::OperandType opnd1Type = opnd1.GetKind(); + uint32 dsize = GetPrimTypeBitSize(primType); + bool is64Bits = (dsize == k64BitSize); + + if (opndM0Type != Operand::kOpdRegister) { + SelectMadd(resOpnd, SelectCopy(opndM0, primType, primType), opndM1, opnd1, primType); + return; + } else if (opndM1Type != Operand::kOpdRegister) { + SelectMadd(resOpnd, opndM0, SelectCopy(opndM1, primType, primType), opnd1, primType); + return; + } else if (opnd1Type != Operand::kOpdRegister) { + SelectMadd(resOpnd, opndM0, opndM1, SelectCopy(opnd1, primType, primType), primType); + return; + } + + ASSERT(IsPrimitiveInteger(primType), "NYI MAdd"); + MOperator mOp = is64Bits ? MOP_xmaddrrrr : MOP_wmaddrrrr; + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, resOpnd, opndM0, opndM1, opnd1)); +} + Operand &AArch64CGFunc::SelectCGArrayElemAdd(BinaryNode &node) { BaseNode *opnd0 = node.Opnd(0); BaseNode *opnd1 = node.Opnd(1); @@ -3737,7 +3864,7 @@ Operand *AArch64CGFunc::SelectBnot(UnaryNode &node, Operand &opnd0) { Operand *AArch64CGFunc::SelectExtractbits(ExtractbitsNode &node, Operand &srcOpnd) { PrimType dtype = node.GetPrimType(); RegOperand &resOpnd = CreateRegisterOperandOfType(dtype); - bool isSigned = IsSignedInteger(dtype); + bool isSigned = (node.GetOpCode() == OP_sext) ? true : (node.GetOpCode() == OP_zext) ? false : IsSignedInteger(dtype); uint8 bitOffset = node.GetBitsOffset(); uint8 bitSize = node.GetBitsSize(); bool is64Bits = (GetPrimTypeBitSize(dtype) == k64BitSize); @@ -4256,7 +4383,7 @@ void AArch64CGFunc::SelectCvtInt2Int(const BaseNode *parent, Operand *&resOpnd, } else { /* same size, so resOpnd can be set */ if ((mirModule.IsJavaModule()) || (IsSignedInteger(fromType) == IsSignedInteger(toType)) || - (GetPrimTypeSize(toType) > k4BitSize)) { + (GetPrimTypeSize(toType) >= k4BitSize)) { AArch64RegOperand *reg = static_cast(resOpnd); reg->SetRegisterNumber(static_cast(opnd0)->GetRegisterNumber()); } else if (IsUnsignedInteger(toType)) { @@ -4268,9 +4395,6 @@ void AArch64CGFunc::SelectCvtInt2Int(const BaseNode *parent, Operand *&resOpnd, case PTY_u16: mop = MOP_xuxth32; break; - case PTY_u32: - mop = MOP_xuxtw64; - break; default: CHECK_FATAL(0, "Unhandled unsigned convert"); } @@ -4286,9 +4410,6 @@ void AArch64CGFunc::SelectCvtInt2Int(const BaseNode *parent, Operand *&resOpnd, case PTY_i16: mop = (size > k4BitSize) ? MOP_xsxth64 : MOP_xsxth32; break; - case PTY_i32: - mop = MOP_xsxtw64; - break; default: CHECK_FATAL(0, "Unhandled unsigned convert"); } @@ -4805,8 +4926,8 @@ Operand &AArch64CGFunc::GetTargetRetOperand(PrimType primType, int32 sReg) { AArch64reg pReg; if (sReg < 0) { return GetOrCreatePhysicalRegisterOperand( - IsPrimitiveFloat(primType) || (GetPrimTypeLanes(primType) > 0) ? S0 : R0, - bitSize, GetRegTyFromPrimTy(primType)); + IsPrimitiveFloat(primType) || (GetPrimTypeLanes(primType) > 0) ? S0 : R0, + bitSize, GetRegTyFromPrimTy(primType)); } else { switch (sReg) { case kSregRetval0: @@ -5635,7 +5756,11 @@ AArch64RegOperand *AArch64CGFunc::SelectParmListDreadAccessField(const MIRSymbol } else { memOpnd = &GetOrCreateMemOpnd(sym, (kSizeOfPtr * parmNum + offset), memSize); } - GetCurBB()->AppendInsn(cg->BuildInstruction(PickLdInsn(dataSizeBits, primType), *parmOpnd, *memOpnd)); + MOperator selectedMop = PickLdInsn(dataSizeBits, primType); + if (!IsOperandImmValid(selectedMop, memOpnd, kInsnSecondOpnd)) { + memOpnd = &SplitOffsetWithAddInstruction(*static_cast(memOpnd), dataSizeBits); + } + GetCurBB()->AppendInsn(cg->BuildInstruction(selectedMop, *parmOpnd, *memOpnd)); return parmOpnd; } @@ -5662,7 +5787,11 @@ void AArch64CGFunc::CreateCallStructParamPassByReg(AArch64reg reg, MemOperand &m ASSERT(0, "CreateCallStructParamPassByReg: Unknown state"); } - GetCurBB()->AppendInsn(cg->BuildInstruction(PickLdInsn(dataSizeBits, pType), *parmOpnd, memOpnd)); + MOperator selectedMop = PickLdInsn(dataSizeBits, pType); + if (!IsOperandImmValid(selectedMop, &memOpnd, kInsnSecondOpnd)) { + memOpnd = SplitOffsetWithAddInstruction(static_cast(memOpnd), dataSizeBits); + } + GetCurBB()->AppendInsn(cg->BuildInstruction(selectedMop, *parmOpnd, memOpnd)); srcOpnds.PushOpnd(*parmOpnd); } @@ -6532,8 +6661,8 @@ AArch64RegOperand &AArch64CGFunc::GetOrCreatePhysicalRegisterOperand(AArch64reg if (size <= k32BitSize) { size = k32BitSize; aarch64PhyRegIdx = aarch64PhyRegIdx << 1; - } else { - size = size == k128BitSize ? k128BitSize : k64BitSize; + } else { + size = (size == k128BitSize) ? k128BitSize : k64BitSize; aarch64PhyRegIdx = (aarch64PhyRegIdx << 1) + 1; } ASSERT(aarch64PhyRegIdx < k256BitSize, "phyRegOperandTable index out of range"); @@ -7984,7 +8113,9 @@ RegOperand *AArch64CGFunc::SelectVectorFromScalar(IntrinsicopNode &intrnNode) { ConstvalNode *constvalNode = static_cast(argExpr); MIRConst *mirConst = constvalNode->GetConstVal(); int32 val = safe_cast(mirConst)->GetValue(); - if (val >= -128 && val <= 255) { + const int32 kMinImmVal = -128; + const int32 kMaxImmVal = 255; + if (val >= kMinImmVal && val <= kMaxImmVal) { Insn *insn = &GetCG()->BuildInstruction(MOP_vmovvi, *res, *immOpnd); static_cast(insn)->PushRegSpecEntry(vecSpec); GetCurBB()->AppendInsn(*insn); @@ -8103,7 +8234,7 @@ RegOperand *AArch64CGFunc::SelectVectorSetElement(IntrinsicopNode &intrnNode) { VectorRegSpec *vecSpecSrc = GetMemoryPool()->New(); vecSpecSrc->vecLaneMax = GetPrimTypeLanes(vType); - BaseNode *arg2 = intrnNode.Opnd(2); /* lane const operand */ + BaseNode *arg2 = intrnNode.Opnd(kInsnThirdOpnd); /* lane const operand */ Operand *opnd2 = HandleExpr(intrnNode, *arg2); if (opnd2->IsConstImmediate()) { ConstvalNode *constvalNode = static_cast(arg2); @@ -8137,10 +8268,10 @@ RegOperand *AArch64CGFunc::SelectVectorMerge(IntrinsicopNode &intrnNode) { VectorRegSpec *vecSpecOpd2 = GetMemoryPool()->New(); vecSpecOpd2->vecLaneMax = GetPrimTypeLanes(o2Type); - BaseNode *arg3 = intrnNode.Opnd(2); /* lane const operand */ + BaseNode *arg3 = intrnNode.Opnd(kInsnThirdOpnd); /* lane const operand */ Operand *opnd3 = HandleExpr(intrnNode, *arg3); if (!opnd3->IsConstImmediate()) { - CHECK_FATAL(0, "VectorMerge does not have lane const"); + CHECK_FATAL(0, "VectorMerge does not have lane const"); } Insn *insn = &GetCG()->BuildInstruction(MOP_vextvvv, *res, *opnd1, *opnd2, *opnd3); @@ -8163,7 +8294,7 @@ RegOperand *AArch64CGFunc::SelectVectorReverse(IntrinsicopNode &intrnNode, uint3 VectorRegSpec *vecSpecSrc = GetMemoryPool()->New(); vecSpecSrc->vecLaneMax = GetPrimTypeLanes(srcType); - MOperator mOp = size >= 64 ? MOP_vrev64vv : (size >= 32 ? MOP_vrev32vv : MOP_vrev16vv); + MOperator mOp = size >= k64BitSize ? MOP_vrev64vv : (size >= k32BitSize ? MOP_vrev32vv : MOP_vrev16vv); Insn *insn = &GetCG()->BuildInstruction(mOp, *res, srcOpnd); static_cast(insn)->PushRegSpecEntry(vecSpecDest); static_cast(insn)->PushRegSpecEntry(vecSpecSrc); @@ -8240,15 +8371,15 @@ RegOperand *AArch64CGFunc::SelectVectorCompare(IntrinsicopNode &intrnNode, V_CND MOperator mOp; switch (cc) { - case CGFunc::v_eq: mOp = MOP_vcmeqvvv; - break; - case CGFunc::v_ge: mOp = MOP_vcmgevvv; - break; - case CGFunc::v_gt: mOp = MOP_vcmgtvvv; - break; - case CGFunc::v_lt: mOp = MOP_vcmltvvv; - break; - default: CHECK_FATAL(0, "Invalid cc in vector compare"); + case CGFunc::v_eq: mOp = MOP_vcmeqvvv; + break; + case CGFunc::v_ge: mOp = MOP_vcmgevvv; + break; + case CGFunc::v_gt: mOp = MOP_vcmgtvvv; + break; + case CGFunc::v_lt: mOp = MOP_vcmltvvv; + break; + default: CHECK_FATAL(0, "Invalid cc in vector compare"); } Insn *insn = &GetCG()->BuildInstruction(mOp, *res, opnd1, opnd2); static_cast(insn)->PushRegSpecEntry(vecSpecDest); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp index eb83856f46fb3ecac9cbd284c9d27f8ab2722638..0f8b6018e7e56b6c34a8c53b8ef44524f45faa27 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp @@ -226,6 +226,9 @@ bool ForwardPropPattern::CheckCondition(Insn &insn) { } Operand &firstOpnd = insn.GetOperand(kInsnFirstOpnd); Operand &secondOpnd = insn.GetOperand(kInsnSecondOpnd); + if (firstOpnd.GetSize() != secondOpnd.GetSize()) { + return false; + } RegOperand &firstRegOpnd = static_cast(firstOpnd); RegOperand &secondRegOpnd = static_cast(secondOpnd); uint32 firstRegNO = firstRegOpnd.GetRegisterNumber(); @@ -349,7 +352,9 @@ bool BackPropPattern::CheckAndGetOpnd(Insn &insn) { if (RegOperand::IsSameReg(firstOpnd, secondOpnd)) { return false; } - + if (firstOpnd.GetSize() != secondOpnd.GetSize()) { + return false; + } firstRegOpnd = &static_cast(firstOpnd); secondRegOpnd = &static_cast(secondOpnd); if (firstRegOpnd->IsZeroRegister() || !firstRegOpnd->IsVirtualRegister() || !secondRegOpnd->IsVirtualRegister()) { @@ -724,7 +729,10 @@ uint32 RedundantUxtPattern::GetInsnValidBit(Insn &insn) { uint32 RedundantUxtPattern::GetMaximumValidBit(Insn &insn, uint8 index, InsnSet &visitedInsn) const { InsnSet defInsnSet = cgFunc.GetRD()->FindDefForRegOpnd(insn, index); - ASSERT(!defInsnSet.empty(), "operand must be defined before used"); + if (defInsnSet.empty()) { + /* disable opt when there is no def point. */ + return k64BitSize; + } uint32 validBit = 0; uint32 nMaxValidBit = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp index 5237ed76d1fc62843e94a8238a965142114832da..1467725570b72020482c4ba008e97bec489d50ae 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -1090,7 +1090,6 @@ void AArch64Insn::Emit(const CG &cg, Emitter &emitter) const { } regOpnd->SetVecLanePosition(vecSpec->vecLane); regOpnd->SetVecLaneSize(vecSpec->vecLaneMax); - } } opnds[seq[i]]->Emit(emitter, md->operand[seq[i]]); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index 2eb3b6b5069fbde8925d1cf1d27e2a4d82dfc170..aa499e6f0f12494ea4d6f3b9209cac4faf0517f2 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -58,6 +58,14 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF insn.SetOperand(i, newMemOpnd); } } + if (ofstOpnd->GetVary() == kNotVary) { + bool condition = aarchCGFunc.IsOperandImmValid(insn.GetMachineOpcode(), &memOpnd, i); + if (!condition) { + AArch64MemOperand &newMemOpnd = aarchCGFunc.SplitOffsetWithAddInstruction( + memOpnd, memOpnd.GetSize(), static_cast(R17), false, &insn); + insn.SetOperand(i, newMemOpnd); + } + } } else if (opnd.IsIntImmediate()) { AdjustmentOffsetForImmOpnd(insn, i, aarchCGFunc); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp index f2a16c709f19143610344abf9970a659c573619f..e34b9b8723ac1244bd247cebee35d6e6632dd9b7 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp @@ -84,15 +84,15 @@ void AArch64RegOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { break; } case kRegTyFloat: { - ASSERT((opndSize == k8BitSize || opndSize == k16BitSize || opndSize == k32BitSize || opndSize == k64BitSize - || opndSize == k128BitSize), "illegal register size"); + ASSERT((opndSize == k8BitSize || opndSize == k16BitSize || opndSize == k32BitSize || + opndSize == k64BitSize || opndSize == k128BitSize), "illegal register size"); int32 laneSize = GetVecLaneSize(); if (static_cast(opndProp)->IsVectorOperand() && laneSize != 0) { std::string width; if (opndSize == k128BitSize) { - width = laneSize == 16 ? "b" : (laneSize == 8 ? "h" : (laneSize == 4 ? "s" : "d")); + width = laneSize == k16BitSize ? "b" : (laneSize == k8BitSize ? "h" : (laneSize == k4BitSize ? "s" : "d")); } else if (opndSize == k64BitSize) { - width = laneSize == 8 ? "b" : (laneSize == 4 ? "h" : "s"); + width = laneSize == k8BitSize ? "b" : (laneSize == k4BitSize ? "h" : "s"); } int16 lanePos = GetVecLanePosition(); emitter.Emit(AArch64CG::vectorRegNames[regNO]); @@ -206,8 +206,6 @@ void StImmOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { } } -const int32 AArch64MemOperand::kMaxPimms[4] = { kMaxPimm8, kMaxPimm16, kMaxPimm32, kMaxPimm64 }; - Operand *AArch64MemOperand::GetOffset() const { switch (addrMode) { case kAddrModeBOi: @@ -230,7 +228,8 @@ void AArch64MemOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { #if DEBUG const AArch64MD *md = &AArch64CG::kMd[emitter.GetCurrentMOP()]; bool isLDSTpair = md->IsLoadStorePair(); - ASSERT(md->Is64Bit() || md->GetOperandSize() <= k32BitSize || md->GetOperandSize() == k128BitSize, "unexpected opnd size"); + ASSERT(md->Is64Bit() || md->GetOperandSize() <= k32BitSize || md->GetOperandSize() == k128BitSize, + "unexpected opnd size"); #endif if (addressMode == AArch64MemOperand::kAddrModeBOi) { emitter.Emit("["); @@ -250,7 +249,6 @@ void AArch64MemOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { * The ARMv8-A architecture allows many types of load and store accesses to be arbitrarily aligned. * The Cortex- A57 processor handles most unaligned accesses without performance penalties. */ - //ASSERT(!IsOffsetMisaligned(md->GetOperandSize()), "should not be OffsetMisaligned"); #if DEBUG if (IsOffsetMisaligned(md->GetOperandSize())) { INFO(kLncInfo, "The Memory operand's offset is misaligned:", ""); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 3cd16e26c986ee1b5ed4aa4286b03db0bceb3816..561106aa209bfa3b9f856b2d210e3b49484a07be 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -26,7 +26,6 @@ const std::set kFrameWhiteListFunc { bool IsFuncNeedFrame(const std::string &funcName) { return kFrameWhiteListFunc.find(funcName) != kFrameWhiteListFunc.end(); } -constexpr uint32 k2BitSize = 2; constexpr int32 kSoeChckOffset = 8192; enum RegsPushPop : uint8 { diff --git a/src/mapleall/maple_be/src/cg/cg_cfg.cpp b/src/mapleall/maple_be/src/cg/cg_cfg.cpp index 3d9d7e5230387acc448f5afd371b760deb46e384..86533565a01ad3efd261fbab5b733d9b8e5f299c 100644 --- a/src/mapleall/maple_be/src/cg/cg_cfg.cpp +++ b/src/mapleall/maple_be/src/cg/cg_cfg.cpp @@ -389,6 +389,9 @@ void CGCFG::RemoveBB(BB &curBB, bool isGotoIf) { } for (BB *preBB : curBB.GetPreds()) { + if (preBB->GetKind() == BB::kBBIgoto) { + return; + } /* * If curBB is the target of its predecessor, change * the jump target. diff --git a/src/mapleall/maple_be/src/cg/cg_option.cpp b/src/mapleall/maple_be/src/cg/cg_option.cpp index c82a76150d5fe0522839179b75f002a92b3cc073..33ba6d90b323fc9faa05ac6dfba7450b36931778 100644 --- a/src/mapleall/maple_be/src/cg/cg_option.cpp +++ b/src/mapleall/maple_be/src/cg/cg_option.cpp @@ -65,7 +65,7 @@ bool CGOptions::doCFGO = false; bool CGOptions::doICO = false; bool CGOptions::doStoreLoadOpt = false; bool CGOptions::doGlobalOpt = false; -bool CGOptions::doMultiPassColorRA = false; +bool CGOptions::doMultiPassColorRA = true; bool CGOptions::doPrePeephole = false; bool CGOptions::doPeephole = false; bool CGOptions::doSchedule = false; @@ -1370,7 +1370,7 @@ bool CGOptions::SolveOptions(const std::vector