diff --git a/src/mapleall/maple_be/include/be/becommon.h b/src/mapleall/maple_be/include/be/becommon.h index 35d2bcab17cd523b7167b8b090171daed801c296..1d48d04582a7da451f9c97435f5b2ac31854af32 100644 --- a/src/mapleall/maple_be/include/be/becommon.h +++ b/src/mapleall/maple_be/include/be/becommon.h @@ -131,6 +131,8 @@ class BECommon { BaseNode *GetAddressOfNode(const BaseNode &node); + bool CallIsOfAttr(FuncAttrKind attr, StmtNode *narynode); + PrimType GetAddressPrimType() const { return LOWERED_PTR_TYPE; } diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_abi.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_abi.h index c16e16e9fe08e9f4b46bc38cfc2c3e58bd5209ef..7e07c272d5b1cf2c750d536dafc7b63088c4d4d9 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_abi.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_abi.h @@ -89,7 +89,7 @@ class ParmLocator { ~ParmLocator() = default; /* Return size of aggregate structure copy on stack. */ - int32 LocateNextParm(MIRType &mirType, PLocInfo &pLoc, bool isFirst = false); + int32 LocateNextParm(MIRType &mirType, PLocInfo &pLoc, bool isFirst = false, MIRFunction *func = nullptr); int32 LocateRetVal(MIRType &retType, PLocInfo &ploc); void InitPLocInfo(PLocInfo &pLoc) const; 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 2b93b15fda1cfb4d2ec38bd33295456cb53bdaad..52461d771ba239ec04d86dddbcfbb46636d2b757 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h @@ -89,6 +89,14 @@ class AArch64RegOperand : public RegOperand { return memPool.Clone(*this); } + void SetIF64Vec() { + if64Vec = true; + } + + bool GetIF64Vec() { + return if64Vec; + } + void SetVecLanePosition(int32 pos) { vecLane = pos; } @@ -131,6 +139,7 @@ class AArch64RegOperand : public RegOperand { uint32 flag; int16 vecLane = -1; /* -1 for whole reg, 0 to 15 to specify each lane one at a time */ uint16 vecLaneSize = 0; /* Number of lanes */ + bool if64Vec = false; /* operand returning 64x1's int value in FP/Simd register */ }; /* diff --git a/src/mapleall/maple_be/src/be/becommon.cpp b/src/mapleall/maple_be/src/be/becommon.cpp index ae8e329ab73b93e933a0eb45ddccc0ace4acaeb7..656055eb5571cbd54e4c8283e134f04d35e23c53 100644 --- a/src/mapleall/maple_be/src/be/becommon.cpp +++ b/src/mapleall/maple_be/src/be/becommon.cpp @@ -746,4 +746,86 @@ BaseNode *BECommon::GetAddressOfNode(const BaseNode &node) { return nullptr; } } + +bool BECommon::CallIsOfAttr(FuncAttrKind attr, StmtNode *narynode) { + return false; + + /* For now, all 64x1_t types object are not propagated to become pregs by mplme, so the following + is not needed for now. We need to revisit this later when types are enhanced with attributes */ +#if TO_BE_RESURRECTED + bool attrFunc = false; + if (narynode->GetOpCode() == OP_call) { + CallNode *callNode = static_cast(narynode); + MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + attrFunc = mirModule.GetSrcLang() == kSrcLangC && func->GetAttr(attr) ? true : false; + } else if (narynode->GetOpCode() == OP_icall) { + IcallNode *icallNode = static_cast(narynode); + BaseNode *fNode = icallNode->Opnd(0); + MIRFuncType *fType = nullptr; + MIRPtrType *pType = nullptr; + if (fNode->GetOpCode() == OP_dread) { + DreadNode *dNode = static_cast(fNode); + MIRSymbol *symbol = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dNode->GetStIdx()); + pType = static_cast(symbol->GetType()); + MIRType *ty = pType; + if (dNode->GetFieldID() != 0) { + ASSERT(ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeClass, ""); + FieldPair thepair; + if (ty->GetKind() == kTypeStruct) { + thepair = static_cast(ty)->TraverseToField(dNode->GetFieldID()); + } else { + thepair = static_cast(ty)->TraverseToField(dNode->GetFieldID()); + } + pType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first)); + } + fType = static_cast(pType->GetPointedType()); + //attrFunc = fType->isVarArgs; + } else if (fNode->GetOpCode() == OP_iread) { + IreadNode *iNode = static_cast(fNode); + MIRPtrType *pointerty = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iNode->GetTyIdx())); + MIRType *pointedType = pointerty->GetPointedType(); + if (iNode->GetFieldID() != 0) { + pointedType = static_cast(pointedType)->GetFieldType(iNode->GetFieldID()); + } + if (pointedType->GetKind() == kTypeFunction) { + fType = static_cast(pointedType); + } else if (pointedType->GetKind() == kTypePointer) { + return false; /* assert? */ + } + //attrFunc = fType->isVarArgs; + } else if (fNode->GetOpCode() == OP_select) { + TernaryNode *sNode = static_cast(fNode); + BaseNode *expr = sNode->Opnd(1); + // both function ptrs under select should have the same signature, chk op1 only + AddroffuncNode *afNode = static_cast(expr); + MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(afNode->GetPUIdx()); + attrFunc = mirModule.GetSrcLang() == kSrcLangC && func->GetAttr(attr); + } else if (fNode->GetOpCode() == OP_regread) { + RegreadNode *rNode = static_cast(fNode); + PregIdx pregidx = rNode->GetRegIdx(); + MIRPreg *preg = mirModule.CurFunction()->GetPregTab()->PregFromPregIdx(pregidx); + MIRType *type = preg->GetMIRType(); + if (type == nullptr) { + return false; + } + MIRPtrType *pType = static_cast(type); + type = pType->GetPointedType(); + if (type == nullptr) { + return false; + } + //MIRFuncType *fType = static_cast(type); + //attrFunc = fType->isVarArgs; + } else if (fNode->GetOpCode() == OP_retype) { + RetypeNode *rNode = static_cast(fNode); + pType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(rNode->GetTyIdx())); + fType = static_cast(pType->GetPointedType()); + //attrFunc = fType->isVarArgs; + } else { + return false; /* assert? */ + } + } + return attrFunc; +#endif +} + } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index d89259cb83d01eb9cd23a2dbef623b01b67936fb..490632e352a682c061bb6f6130c8139451639e6a 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -1032,8 +1032,14 @@ DassignNode *CGLowerer::SaveReturnValueInLocal(StIdx stIdx, uint16 fieldID) { var = GetCurrentFunc()->GetSymbolTabItem(stIdx.Idx()); } CHECK_FATAL(var != nullptr, "var should not be nullptr"); + PrimType pType; + if (var->GetAttr(ATTR_oneelem_simd)) { + pType = PTY_f64; + } else { + pType = GlobalTables::GetTypeTable().GetTypeTable().at(var->GetTyIdx())->GetPrimType(); + } RegreadNode *regRead = mirModule.GetMIRBuilder()->CreateExprRegread( - GlobalTables::GetTypeTable().GetTypeTable().at(var->GetTyIdx())->GetPrimType(), -kSregRetval0); + pType, -kSregRetval0); return mirModule.GetMIRBuilder()->CreateStmtDassign(*var, fieldID, regRead); } @@ -1180,10 +1186,25 @@ BlockNode *CGLowerer::GenBlockNode(StmtNode &newCall, const CallReturnVector &p2 } else { PregIdx pregIdx = static_cast(regFieldPair.GetPregIdx()); MIRPreg *mirPreg = GetCurrentFunc()->GetPregTab()->PregFromPregIdx(pregIdx); - RegreadNode *regNode = mirModule.GetMIRBuilder()->CreateExprRegread(mirPreg->GetPrimType(), -kSregRetval0); - RegassignNode *regAssign = - mirModule.GetMIRBuilder()->CreateStmtRegassign(mirPreg->GetPrimType(), regFieldPair.GetPregIdx(), - regNode); + bool is64x1vec = beCommon.CallIsOfAttr(FUNCATTR_oneelem_simd, &newCall); + PrimType pType = is64x1vec ? PTY_f64 : mirPreg->GetPrimType(); + RegreadNode *regNode = mirModule.GetMIRBuilder()->CreateExprRegread(pType, -kSregRetval0); + RegassignNode *regAssign; + if (is64x1vec && IsPrimitiveInteger(mirPreg->GetPrimType())) { // not f64 + MIRType *to; + if (IsUnsignedInteger(mirPreg->GetPrimType())) { + to = GlobalTables::GetTypeTable().GetUInt64(); + } else { + to = GlobalTables::GetTypeTable().GetInt64(); + } + MIRType *from = GlobalTables::GetTypeTable().GetDouble(); + BaseNode *rNode = mirModule.GetMIRBuilder()->CreateExprRetype(*to, *from, regNode); + regAssign = mirModule.GetMIRBuilder()->CreateStmtRegassign(mirPreg->GetPrimType(), + regFieldPair.GetPregIdx(), rNode); + } else { + regAssign = mirModule.GetMIRBuilder()->CreateStmtRegassign(mirPreg->GetPrimType(), + regFieldPair.GetPregIdx(), regNode); + } blk->AddStatement(regAssign); dStmt = regAssign; } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_abi.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_abi.cpp index 111b65a0e1d3eb0f2fded527b69a3094ea1dc02b..b207c69997ce568d7533ad67080cc0d360aff257 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_abi.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_abi.cpp @@ -389,12 +389,23 @@ int32 ParmLocator::LocateRetVal(MIRType &retType, PLocInfo &pLoc) { * LocateNextParm should be called with each parameter in the parameter list * starting from the beginning, one call per parameter in sequence; it returns * the information on how each parameter is passed in pLoc + * + * *** CAUTION OF USE: *** + * If LocateNextParm is called for function formals, third argument isFirst is true. + * LocateNextParm is then checked against a function parameter list. All other calls + * of LocateNextParm are against caller's argument list must not have isFirst set, + * or it will be checking the caller's enclosing function. */ -int32 ParmLocator::LocateNextParm(MIRType &mirType, PLocInfo &pLoc, bool isFirst) { +int32 ParmLocator::LocateNextParm(MIRType &mirType, PLocInfo &pLoc, bool isFirst, MIRFunction *tFunc) { InitPLocInfo(pLoc); + bool is64x1vec = false; + if (tFunc != nullptr && tFunc->GetParamSize() > 0) { + is64x1vec = tFunc->GetNthParamAttr(paramNum).GetAttr(ATTR_oneelem_simd) != 0; + } + if (isFirst) { - MIRFunction *func = const_cast(beCommon.GetMIRModule().CurFunction()); + MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); if (beCommon.HasFuncReturnType(*func)) { uint32 size = beCommon.GetTypeSize(beCommon.GetFuncReturnType(*func)); if (size == 0) { @@ -463,7 +474,7 @@ int32 ParmLocator::LocateNextParm(MIRType &mirType, PLocInfo &pLoc, bool isFirst case PTY_i64: /* Rule C.7 */ typeSize = k8ByteSize; - pLoc.reg0 = AllocateGPRegister(); + pLoc.reg0 = is64x1vec ? AllocateSIMDFPRegister() : AllocateGPRegister(); ASSERT(nextGeneralRegNO <= AArch64Abi::kNumIntParmRegs, "RegNo should be pramRegNO"); break; /* 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 f7bba6ee80e2a112fceaf570f0cf44bae7942587..72478b54263dcef1bbe6f7da053815ddcfcbaee7 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -47,7 +47,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL } for (uint32 i = start; i < numFormal; ++i) { MIRType *ty = aarchCGFunc->GetFunction().GetNthParamType(i); - parmlocator.LocateNextParm(*ty, ploc, i == 0); + parmlocator.LocateNextParm(*ty, ploc, i == 0, &aarchCGFunc->GetFunction()); if (ploc.reg0 == kRinvalid) { continue; } @@ -433,7 +433,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { } for (uint32 i = start; i < formalCount; ++i) { MIRType *ty = aarchCGFunc->GetFunction().GetNthParamType(i); - parmlocator.LocateNextParm(*ty, ploc, i == 0); + parmlocator.LocateNextParm(*ty, ploc, i == 0, &aarchCGFunc->GetFunction()); MIRSymbol *sym = aarchCGFunc->GetFunction().GetFormal(i); /* load locarefvar formals to store in the reflocals. */ 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 5476deec887346d6198a53f661d2e35ea2530ba7..77a4149820ae3ffbffd28c0851aa7631719be6f9 100755 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1847,7 +1847,7 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { MIRSymbol *retSt = GetBecommon().GetMIRModule().CurFunction()->GetFormal(0); if (retSt == addrSym) { /* return value */ - parmlocator.LocateNextParm(*lhsType, pLoc, true); + parmlocator.LocateNextParm(*lhsType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); } else { parmlocator.InitPLocInfo(pLoc); } @@ -6549,10 +6549,44 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, AArch64ListOperand &srcOp PLocInfo ploc; int32 structCopyOffset = GetMaxParamStackSize() - GetStructCopySize(); for (uint32 pnum = 0; i < naryNode.NumOpnds(); ++i, ++pnum) { + bool is64x1vec = false; MIRType *ty = nullptr; BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + switch (argExpr->op) { + case OP_dread: { + DreadNode *dNode = static_cast(argExpr); + MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(dNode->GetStIdx()); + if (dNode->GetFieldID() != 0) { + MIRStructType *structType = static_cast(symbol->GetType()); + ASSERT(structType != nullptr, "SelectParmList: non-zero fieldID for non-structure"); + FieldAttrs fa = structType->GetFieldAttrs(dNode->GetFieldID()); + is64x1vec = fa.GetAttr(FLDATTR_oneelem_simd) ? true : false; + } else { + is64x1vec = symbol->GetAttr(ATTR_oneelem_simd) ? true : false; + } + break; + } + case OP_iread: { + IreadNode *iNode = static_cast(argExpr); + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iNode->GetTyIdx()); + MIRPtrType *ptrTyp = static_cast(type); + ASSERT(ptrTyp != nullptr, "expect a pointer type at iread node"); + MIRType *pointedTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTyp->GetPointedTyIdx()); + if (iNode->GetFieldID() != 0) { + MIRStructType *structType = static_cast(pointedTy); + FieldAttrs fa = structType->GetFieldAttrs(iNode->GetFieldID()); + is64x1vec = fa.GetAttr(FLDATTR_oneelem_simd) ? true : false; + } else { + TypeAttrs ta = static_cast(ptrTyp)->GetTypeAttrs(); + is64x1vec = ta.GetAttr(ATTR_oneelem_simd) ? true : false; + } + break; + } + default: + break; + } /* use alloca */ if (primType == PTY_agg) { SelectParmListForAggregate(*argExpr, srcOpnds, parmLocator, structCopyOffset); @@ -6561,6 +6595,9 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, AArch64ListOperand &srcOp ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(primType)]; RegOperand *expRegOpnd = nullptr; Operand *opnd = HandleExpr(naryNode, *argExpr); + if (opnd->GetKind() == Operand::kOpdRegister && static_cast(opnd)->GetIF64Vec()) { + is64x1vec = true; + } if (!opnd->IsRegister()) { opnd = &LoadIntoRegister(*opnd, primType); } @@ -6572,6 +6609,12 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, AArch64ListOperand &srcOp } else { parmLocator.LocateNextParm(*ty, ploc); } + /* is64x1vec should be an int64 value in an FP/simd reg for ABI compliance, + convert R-reg to equivalent V-reg */ + if (is64x1vec && ploc.reg0 != kRinvalid && ploc.reg0 < R7) { + ploc.reg0 = AArch64Abi::floatParmRegs[(int)ploc.reg0 - 1]; + primType = PTY_f64; + } if (ploc.reg0 != kRinvalid) { /* load to the register. */ CHECK_FATAL(expRegOpnd != nullptr, "null ptr check"); AArch64RegOperand &parmRegOpnd = GetOrCreatePhysicalRegisterOperand(ploc.reg0, expRegOpnd->GetSize(), @@ -7062,28 +7105,41 @@ void AArch64CGFunc::SelectComment(CommentNode &comment) { } void AArch64CGFunc::SelectReturn(Operand *opnd0) { - ReturnMechanism retMech(*(GetFunction().GetReturnType()), GetBecommon()); + bool is64x1vec = GetFunction().GetAttr(FUNCATTR_oneelem_simd) ? true : false; + MIRType *floatType = GlobalTables::GetTypeTable().GetDouble(); + MIRType *retTyp = is64x1vec ? floatType : GetFunction().GetReturnType(); + ReturnMechanism retMech(*retTyp, GetBecommon()); if (retMech.GetRegCount() > 0) { CHECK_FATAL(opnd0 != nullptr, "opnd0 must not be nullptr"); + RegType regTyp = is64x1vec ? kRegTyFloat : GetRegTyFromPrimTy(retMech.GetPrimTypeOfReg0()); if (opnd0->IsRegister()) { RegOperand *regOpnd = static_cast(opnd0); if (regOpnd->GetRegisterNumber() != retMech.GetReg0()) { AArch64RegOperand &retOpnd = - GetOrCreatePhysicalRegisterOperand(retMech.GetReg0(), regOpnd->GetSize(), - GetRegTyFromPrimTy(retMech.GetPrimTypeOfReg0())); + GetOrCreatePhysicalRegisterOperand(retMech.GetReg0(), regOpnd->GetSize(), regTyp); SelectCopy(retOpnd, retMech.GetPrimTypeOfReg0(), *regOpnd, retMech.GetPrimTypeOfReg0()); } } else if (opnd0->IsMemoryAccessOperand()) { AArch64MemOperand *memopnd = static_cast(opnd0); AArch64RegOperand &retOpnd = GetOrCreatePhysicalRegisterOperand(retMech.GetReg0(), - GetPrimTypeBitSize(retMech.GetPrimTypeOfReg0()), GetRegTyFromPrimTy(retMech.GetPrimTypeOfReg0())); + GetPrimTypeBitSize(retMech.GetPrimTypeOfReg0()), regTyp); MOperator mOp = PickLdInsn(memopnd->GetSize(), retMech.GetPrimTypeOfReg0()); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, retOpnd, *memopnd)); } else if (opnd0->IsConstImmediate()) { ImmOperand *immOpnd = static_cast(opnd0); - AArch64RegOperand &retOpnd = GetOrCreatePhysicalRegisterOperand(retMech.GetReg0(), - GetPrimTypeBitSize(retMech.GetPrimTypeOfReg0()), GetRegTyFromPrimTy(retMech.GetPrimTypeOfReg0())); - SelectCopy(retOpnd, retMech.GetPrimTypeOfReg0(), *immOpnd, retMech.GetPrimTypeOfReg0()); + if (!is64x1vec) { + AArch64RegOperand &retOpnd = GetOrCreatePhysicalRegisterOperand(retMech.GetReg0(), + GetPrimTypeBitSize(retMech.GetPrimTypeOfReg0()), GetRegTyFromPrimTy(retMech.GetPrimTypeOfReg0())); + SelectCopy(retOpnd, retMech.GetPrimTypeOfReg0(), *immOpnd, retMech.GetPrimTypeOfReg0()); + } else { + PrimType rType = GetFunction().GetReturnType()->GetPrimType(); + RegOperand *reg = &CreateRegisterOperandOfType(rType); + SelectCopy(*reg, rType, *immOpnd, rType); + AArch64RegOperand &retOpnd = GetOrCreatePhysicalRegisterOperand(retMech.GetReg0(), + GetPrimTypeBitSize(PTY_f64), GetRegTyFromPrimTy(PTY_f64)); + Insn &insn = GetCG()->BuildInstruction(MOP_xvmovdr, retOpnd, *reg); + GetCurBB()->AppendInsn(insn); + } } else { CHECK_FATAL(false, "nyi"); } @@ -8840,6 +8896,13 @@ RegOperand *AArch64CGFunc::AdjustOneElementVectorOperand(PrimType oType, RegOper } RegOperand *AArch64CGFunc::SelectVectorFromScalar(PrimType rType, Operand *src, PrimType sType) { + if (!IsPrimitiveVector(rType)) { + RegOperand *res = &CreateRegisterOperandOfType(PTY_f64); + Insn *insn = &GetCG()->BuildInstruction(MOP_xvmovdr, *res, *src); + GetCurBB()->AppendInsn(*insn); /* move xreg to dreg */ + static_cast(res)->SetIF64Vec(); + return static_cast(res); + } RegOperand *res = &CreateRegisterOperandOfType(rType); /* result operand */ VectorRegSpec *vecSpec = GetMemoryPool()->New(); vecSpec->vecLaneMax = GetPrimTypeLanes(rType); @@ -8897,6 +8960,7 @@ RegOperand *AArch64CGFunc::SelectVectorGetHigh(PrimType rType, Operand *src) { GetCurBB()->AppendInsn(*insn); if (oType != rType) { res = AdjustOneElementVectorOperand(oType, res); + static_cast(res)->SetIF64Vec(); } return res; } @@ -8914,6 +8978,7 @@ RegOperand *AArch64CGFunc::SelectVectorGetLow(PrimType rType, Operand *src) { GetCurBB()->AppendInsn(*insn); if (oType != rType) { res = AdjustOneElementVectorOperand(oType, res); + static_cast(res)->SetIF64Vec(); } return res; } @@ -8959,6 +9024,13 @@ RegOperand *AArch64CGFunc::SelectVectorPairwiseAdd(PrimType rType, Operand *src, } RegOperand *AArch64CGFunc::SelectVectorSetElement(Operand *eOpnd, PrimType eType, Operand *vOpnd, PrimType vType, int32 laneNum) { + if (!IsPrimitiveVector(vType)) { + RegOperand *res = &CreateRegisterOperandOfType(PTY_f64); + Insn *insn = &GetCG()->BuildInstruction(MOP_xvmovdr, *res, *eOpnd); + GetCurBB()->AppendInsn(*insn); /* move xreg to dreg */ + static_cast(res)->SetIF64Vec(); + return static_cast(res); + } RegOperand *reg = &CreateRegisterOperandOfType(eType); /* vector element type */ SelectCopy(*reg, eType, *eOpnd, eType); VectorRegSpec *vecSpecSrc = GetMemoryPool()->New(); /* vector operand == result */ @@ -8979,6 +9051,10 @@ RegOperand *AArch64CGFunc::SelectVectorSetElement(Operand *eOpnd, PrimType eType } RegOperand *AArch64CGFunc::SelectVectorMerge(PrimType rTyp, Operand *o1, Operand *o2, int32 index) { + if (!IsPrimitiveVector(rTyp)) { + static_cast(o1)->SetIF64Vec(); + return static_cast(o1); /* 64x1_t, index==0 */ + } RegOperand *res = &CreateRegisterOperandOfType(rTyp); int32 size = GetPrimTypeSize(rTyp); /* 8b or 16b */ VectorRegSpec *vecSpecDest = GetMemoryPool()->New(); 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 c7742ad4f21b646bc023a0ca9cf25e8c52e89457..84d021b0b91dc8cc1b138a89b934365043d46f67 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -137,7 +137,7 @@ void AArch64MemLayout::LayoutVarargParams() { } } MIRType *ty = func->GetNthParamType(i); - parmlocator.LocateNextParm(*ty, ploc); + parmlocator.LocateNextParm(*ty, ploc, i == 0, func); if (ploc.reg0 != kRinvalid) { if (ploc.reg0 >= R0 && ploc.reg0 <= R7) { nIntRegs++; @@ -194,7 +194,7 @@ void AArch64MemLayout::LayoutFormalParams() { bool noStackPara = false; MIRType *ty = mirFunction->GetNthParamType(i); uint32 ptyIdx = ty->GetTypeIndex(); - parmLocator.LocateNextParm(*ty, ploc, i == 0); + parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(ploc.reg0, ploc.reg1, ploc.reg2, ploc.reg3); if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index b3f9b8b276deb1567bbd0ec55026406d0e05dbc6..ea7a3fde5558e4a686434fb8d7f6e66135b95e28 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -367,7 +367,11 @@ Operand *HandleVectorMerge(IntrinsicopNode &intrnNode, CGFunc &cgFunc) { MIRConst *mirConst = static_cast(index)->GetConstVal(); iNum = safe_cast(mirConst)->GetValue(); PrimType ty = intrnNode.Opnd(0)->GetPrimType(); - iNum *= GetPrimTypeSize(ty) / GetPrimTypeLanes(ty); /* 64x2: 0-1 -> 0-8 */ + if (!IsPrimitiveVector(ty)) { + iNum = 0; + } else { + iNum *= GetPrimTypeSize(ty) / GetPrimTypeLanes(ty); /* 64x2: 0-1 -> 0-8 */ + } } else { /* 32x4: 0-3 -> 0-12 */ CHECK_FATAL(0, "VectorMerge does not have const index"); } diff --git a/src/mapleall/maple_be/src/cg/ebo.cpp b/src/mapleall/maple_be/src/cg/ebo.cpp index 87ceadd1f99ddeea546ac953b9aab7408773c88c..a183a3d46a0a125e75bb3ce0f14c8c44d01d6d46 100644 --- a/src/mapleall/maple_be/src/cg/ebo.cpp +++ b/src/mapleall/maple_be/src/cg/ebo.cpp @@ -919,7 +919,13 @@ void Ebo::RemoveUnusedInsns(BB &bb, bool normal) { goto insn_is_needed; } - /* Check all the result can be removed. */ + /* last insn of a 64x1 function is a float, 64x1 function may not be a float */ + if (cgFunc->GetFunction().GetAttr(FUNCATTR_oneelem_simd) && + insnInfo == lastInsnInfo) { + goto insn_is_needed; + } + + /* Check all result that can be removed. */ for (uint32 i = 0; i < resNum; ++i) { opndInfo = insnInfo->result[i]; /* A couple of checks. */