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 195c3ae9ee16c265c32f118a3f8a079286275691..1b8c71267331322e3d9c261baf7a329962a29cab 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -644,6 +644,7 @@ class AArch64CGFunc : public CGFunc { ImmOperand &SplitAndGetRemained(const MemOperand &memOpnd, uint32 bitLen, int64 ofstVal, bool forPair = false); MemOperand &CreateReplacementMemOperand(uint32 bitLen, RegOperand &baseReg, int64 offset); + bool OpndHasStackLoadStore(Insn &insn, Operand &opnd); bool HasStackLoadStore(); MemOperand &LoadStructCopyBase(const MIRSymbol &symbol, int64 offset, int dataSize); 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 23e9b572ae50f63b26e64e52dbddfedb837c4438..7bd233c74736b56cd03c3adc8ad82156c9e96cbc 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -187,7 +187,12 @@ MIRStructType *AArch64CGFunc::GetLmbcStructArgType(BaseNode &stmt, size_t argNo) argNo--; /* 1st opnd of icallproto is funcname, skip it relative to param list */ IcallNode &icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto.GetRetTyIdx()); - MIRFuncType *fType = static_cast(type); + MIRFuncType *fType = nullptr; + if (type->IsMIRPtrType()) { + fType = static_cast(type)->GetPointedFuncType(); + } else { + fType = static_cast(type); + } if (fType->GetParamTypeList().size() < (argNo + 1UL)) { return nullptr; } @@ -2084,8 +2089,12 @@ MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AA if (offset < kMinSimm32) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetInsnBuilder()->BuildInsn(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); + if (immOpnd.IsSingleInstructionMovable()) { + GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd)); + } else { + SelectCopyImm(*baseOpnd, immOpnd, PTY_i64); + GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(MOP_xaddrrr, *baseOpnd, *rfp, *baseOpnd)); + } OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, nullptr, offsetOpnd, nullptr); } else { @@ -2118,16 +2127,32 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { for (uint32 i = 0 ; i < numRegs; ++i) { MemOperand *memOpnd = GenLmbcFpMemOperand(offset + static_cast(i * byteSize), byteSize); RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetInsnBuilder()->BuildInsn(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(PickStInsn(bitlen, primType), srcOpnd, *memOpnd)); } } else { - Operand &srcOpnd = LoadIntoRegister(opnd, primType); - MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetInsnBuilder()->BuildInsn(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + if (primType != PTY_agg) { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + Insn &store = GetInsnBuilder()->BuildInsn(PickStInsn(bitlen, primType), srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } else { + byteSize = rType->GetSize(); + MemOperand *memOpnd; + RegOperand *srcOpnd; + if (byteSize > k8ByteSize) { + memOpnd = GenLmbcFpMemOperand(offset, k8ByteSize); + srcOpnd = &GetOrCreatePhysicalRegisterOperand(AArch64reg(R0), k64BitSize, kRegTyInt); + GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(PickStInsn(k64BitSize, PTY_u64), *srcOpnd, *memOpnd)); + byteSize -= k8ByteSize; + } + PrimType pTy = (byteSize > k4ByteSize) ? PTY_u64 : + ((byteSize > k2ByteSize) ? PTY_u32 : + ((byteSize > k1ByteSize) ? PTY_u16 : PTY_u8)); + bitlen = GetPrimTypeSize(pTy) * kBitsPerByte; + srcOpnd = &GetOrCreatePhysicalRegisterOperand(AArch64reg(R1), bitlen, kRegTyInt); + memOpnd = GenLmbcFpMemOperand(offset + k8ByteSize, byteSize); + GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(PickStInsn(bitlen, pTy), *srcOpnd, *memOpnd)); + } } } @@ -6815,24 +6840,42 @@ void AArch64CGFunc::GenSaveMethodInfoCode(BB &bb) { } } +bool AArch64CGFunc::OpndHasStackLoadStore(Insn &insn, Operand &opnd) { + if (!opnd.IsMemoryAccessOperand()) { + return false; + } + auto &memOpnd = static_cast(opnd); + Operand *base = memOpnd.GetBaseRegister(); + if ((base != nullptr) && base->IsRegister()) { + RegOperand *regOpnd = static_cast(base); + RegType regType = regOpnd->GetRegisterType(); + uint32 regNO = regOpnd->GetRegisterNumber(); + if (((regType != kRegTyCc) && ((regNO == RFP) || (regNO == RSP))) || (regType == kRegTyVary)) { + return true; + } + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + return false; + } + /* lmbc uses ireadoff, not dread. Need to check for previous insn */ + Insn *prevInsn = insn.GetPrev(); + if (prevInsn && prevInsn->GetMachineOpcode() == MOP_xaddrri12) { + RegOperand *pOpnd = static_cast(&prevInsn->GetOperand(1)); + if (pOpnd->GetRegisterType() == kRegTyVary) { + return true; + } + } + } + return false; +} + bool AArch64CGFunc::HasStackLoadStore() { FOR_ALL_BB(bb, this) { FOR_BB_INSNS(insn, bb) { uint32 opndNum = insn->GetOperandSize(); for (uint32 i = 0; i < opndNum; ++i) { Operand &opnd = insn->GetOperand(i); - if (opnd.IsMemoryAccessOperand()) { - auto &memOpnd = static_cast(opnd); - Operand *base = memOpnd.GetBaseRegister(); - - if ((base != nullptr) && base->IsRegister()) { - RegOperand *regOpnd = static_cast(base); - RegType regType = regOpnd->GetRegisterType(); - uint32 regNO = regOpnd->GetRegisterNumber(); - if (((regType != kRegTyCc) && ((regNO == RFP) || (regNO == RSP))) || (regType == kRegTyVary)) { - return true; - } - } + if (OpndHasStackLoadStore(*insn, opnd)) { + return true; } } } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp index 62200d5b3534bb9d76d23fd749c65b7c4cf4bacd..ab22944bc9c3d8d167cfc14c7454346dfc3d96c8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp @@ -40,7 +40,7 @@ void AArch64RegSavesOpt::CreateReachingBBs(ReachInfo &rp, const BB &bb) { } } #if RS_DUMP - M_LOG << " --ReachingBBs for BB " << bb->GetId() << " created\n"; + M_LOG << " --ReachingBBs for BB " << bb.GetId() << " created\n"; #endif } diff --git a/src/mapleall/maple_be/src/cg/regsaves.cpp b/src/mapleall/maple_be/src/cg/regsaves.cpp index d22a816c0db56c88d7aa9f8e7c92b885cf0b761d..d6d40ead95c39921138c21a1e1eec105cf7285c8 100644 --- a/src/mapleall/maple_be/src/cg/regsaves.cpp +++ b/src/mapleall/maple_be/src/cg/regsaves.cpp @@ -24,7 +24,7 @@ namespace maplebe { using namespace maple; bool CgRegSavesOpt::PhaseRun(maplebe::CGFunc &f) { - if (Globals::GetInstance()->GetOptimLevel() <= CGOptions::kLevel1) { + if (Globals::GetInstance()->GetOptimLevel() <= CGOptions::kLevel1 || f.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { return false; }