================ @@ -1151,6 +1154,317 @@ struct TargetLoongArch64 : public GenericTarget<TargetLoongArch64> { return GenericTarget::integerArgumentType(loc, argTy); } + + /// Flatten non-basic types, resulting in an array of types containing only + /// `IntegerType` and `FloatType`. + std::vector<mlir::Type> flattenTypeList(mlir::Location loc, + const mlir::Type type) const { + std::vector<mlir::Type> flatTypes; + + llvm::TypeSwitch<mlir::Type>(type) + .template Case<mlir::IntegerType>([&](mlir::IntegerType intTy) { + if (intTy.getWidth() != 0) + flatTypes.push_back(intTy); + }) + .template Case<mlir::FloatType>([&](mlir::FloatType floatTy) { + if (floatTy.getWidth() != 0) + flatTypes.push_back(floatTy); + }) + .template Case<mlir::ComplexType>([&](mlir::ComplexType cmplx) { + const auto *sem = &floatToSemantics(kindMap, cmplx.getElementType()); + if (sem == &llvm::APFloat::IEEEsingle() || + sem == &llvm::APFloat::IEEEdouble() || + sem == &llvm::APFloat::IEEEquad()) + std::fill_n(std::back_inserter(flatTypes), 2, + cmplx.getElementType()); + else + TODO(loc, "unsupported complx type(not IEEEsingle, IEEEdouble, " + "IEEEquad) as a structure component for BIND(C), " + "VALUE derived type argument and type return"); + }) + .template Case<fir::LogicalType>([&](fir::LogicalType logicalTy) { + const unsigned width = + kindMap.getLogicalBitsize(logicalTy.getFKind()); + if (width != 0) + flatTypes.push_back( + mlir::IntegerType::get(type.getContext(), width)); + }) + .template Case<fir::CharacterType>([&](fir::CharacterType charTy) { + assert(kindMap.getCharacterBitsize(charTy.getFKind()) <= 8 && + "the bit size of characterType as an interoperable type must " + "not exceed 8"); + for (unsigned i = 0; i < charTy.getLen(); ++i) + flatTypes.push_back(mlir::IntegerType::get(type.getContext(), 8)); + }) + .template Case<fir::SequenceType>([&](fir::SequenceType seqTy) { + if (!seqTy.hasDynamicExtents()) { + std::size_t numOfEle = seqTy.getConstantArraySize(); + mlir::Type eleTy = seqTy.getEleTy(); + if (!mlir::isa<mlir::IntegerType, mlir::FloatType>(eleTy)) { + std::vector<mlir::Type> subTypeList = flattenTypeList(loc, eleTy); + if (subTypeList.size() != 0) + for (std::size_t i = 0; i < numOfEle; ++i) + llvm::copy(subTypeList, std::back_inserter(flatTypes)); + } else { + std::fill_n(std::back_inserter(flatTypes), numOfEle, eleTy); + } + } else + TODO(loc, "unsupported dynamic extent sequence type as a structure " + "component for BIND(C), " + "VALUE derived type argument and type return"); + }) + .template Case<fir::RecordType>([&](fir::RecordType recTy) { + for (auto &component : recTy.getTypeList()) { + mlir::Type eleTy = component.second; + std::vector<mlir::Type> subTypeList = flattenTypeList(loc, eleTy); + if (subTypeList.size() != 0) + llvm::copy(subTypeList, std::back_inserter(flatTypes)); + } + }) + .template Case<fir::VectorType>([&](fir::VectorType vecTy) { ---------------- ylzsx wrote:
Thanks for your review. This is my oversight. According to the [LoongArch ABI](https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc#vectors-1), 128-bit vector are passed with two GARs with adjacent numbers (if available), and 256-bit vector are passed on the stack. In other cases, the manual has not explicitly specified. I will modify my code to comply with this ABI requirement and report a TODO for other cases. Specifically, * For a vector smaller than 128 bits, report a TODO. * For a vector equal to 128 bits, return `i128` * For a vector larger than 128 bits, pass it on the stack. I will try to make sure it behaves as similar to clang as possible. Looking forward to your suggestions. https://github.com/llvm/llvm-project/pull/117108 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits