19f6c0056SKolya Panchenko //===- VCIXToLLVMIRTranslation.cpp - Translate VCIX to LLVM IR ------------===//
29f6c0056SKolya Panchenko //
39f6c0056SKolya Panchenko // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49f6c0056SKolya Panchenko // See https://llvm.org/LICENSE.txt for license information.
59f6c0056SKolya Panchenko // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69f6c0056SKolya Panchenko //
79f6c0056SKolya Panchenko //===----------------------------------------------------------------------===//
89f6c0056SKolya Panchenko //
99f6c0056SKolya Panchenko // This file implements a translation between the MLIR VCIX dialect and
109f6c0056SKolya Panchenko // LLVM IR.
119f6c0056SKolya Panchenko //
129f6c0056SKolya Panchenko //===----------------------------------------------------------------------===//
139f6c0056SKolya Panchenko
149f6c0056SKolya Panchenko #include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
159f6c0056SKolya Panchenko #include "mlir/Dialect/LLVMIR/VCIXDialect.h"
169f6c0056SKolya Panchenko #include "mlir/IR/BuiltinAttributes.h"
179f6c0056SKolya Panchenko #include "mlir/IR/Operation.h"
189f6c0056SKolya Panchenko #include "mlir/Target/LLVMIR/ModuleTranslation.h"
199f6c0056SKolya Panchenko
209f6c0056SKolya Panchenko #include "llvm/IR/IRBuilder.h"
219f6c0056SKolya Panchenko #include "llvm/IR/IntrinsicsRISCV.h"
229f6c0056SKolya Panchenko #include "llvm/Support/raw_ostream.h"
239f6c0056SKolya Panchenko
249f6c0056SKolya Panchenko using namespace mlir;
259f6c0056SKolya Panchenko using namespace mlir::LLVM;
269f6c0056SKolya Panchenko using mlir::LLVM::detail::createIntrinsicCall;
279f6c0056SKolya Panchenko
289f6c0056SKolya Panchenko /// Infer XLen type from opcode's type. This is done to avoid passing target
299f6c0056SKolya Panchenko /// option around.
getXlenType(Attribute opcodeAttr,LLVM::ModuleTranslation & moduleTranslation)309f6c0056SKolya Panchenko static llvm::Type *getXlenType(Attribute opcodeAttr,
319f6c0056SKolya Panchenko LLVM::ModuleTranslation &moduleTranslation) {
32*a5757c5bSChristian Sigg auto intAttr = cast<IntegerAttr>(opcodeAttr);
33*a5757c5bSChristian Sigg unsigned xlenWidth = cast<IntegerType>(intAttr.getType()).getWidth();
349f6c0056SKolya Panchenko return llvm::Type::getIntNTy(moduleTranslation.getLLVMContext(), xlenWidth);
359f6c0056SKolya Panchenko }
369f6c0056SKolya Panchenko
379f6c0056SKolya Panchenko /// Return VL for VCIX intrinsic. If vl was previously set, return it,
389f6c0056SKolya Panchenko /// otherwise construct a constant using fixed vector type.
createVL(llvm::IRBuilderBase & builder,llvm::Value * vl,VectorType vtype,llvm::Type * xlen,Location loc,LLVM::ModuleTranslation & moduleTranslation)399f6c0056SKolya Panchenko static llvm::Value *createVL(llvm::IRBuilderBase &builder, llvm::Value *vl,
409f6c0056SKolya Panchenko VectorType vtype, llvm::Type *xlen, Location loc,
419f6c0056SKolya Panchenko LLVM::ModuleTranslation &moduleTranslation) {
429f6c0056SKolya Panchenko if (vl) {
439f6c0056SKolya Panchenko assert(vtype.isScalable() &&
449f6c0056SKolya Panchenko "vl parameter must be set for scalable vectors");
459f6c0056SKolya Panchenko return builder.CreateZExtOrTrunc(vl, xlen);
469f6c0056SKolya Panchenko }
479f6c0056SKolya Panchenko
489f6c0056SKolya Panchenko assert(vtype.getRank() == 1 && "Only 1-d fixed vectors are supported");
499f6c0056SKolya Panchenko return mlir::LLVM::detail::getLLVMConstant(
509f6c0056SKolya Panchenko xlen,
519f6c0056SKolya Panchenko IntegerAttr::get(IntegerType::get(&moduleTranslation.getContext(), 64),
529f6c0056SKolya Panchenko vtype.getShape()[0]),
539f6c0056SKolya Panchenko loc, moduleTranslation);
549f6c0056SKolya Panchenko }
559f6c0056SKolya Panchenko
569f6c0056SKolya Panchenko namespace {
579f6c0056SKolya Panchenko /// Implementation of the dialect interface that converts operations belonging
589f6c0056SKolya Panchenko /// to the VCIX dialect to LLVM IR.
599f6c0056SKolya Panchenko class VCIXDialectLLVMIRTranslationInterface
609f6c0056SKolya Panchenko : public LLVMTranslationDialectInterface {
619f6c0056SKolya Panchenko public:
629f6c0056SKolya Panchenko using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface;
639f6c0056SKolya Panchenko
649f6c0056SKolya Panchenko /// Translates the given operation to LLVM IR using the provided IR builder
659f6c0056SKolya Panchenko /// and saving the state in `moduleTranslation`.
669f6c0056SKolya Panchenko LogicalResult
convertOperation(Operation * op,llvm::IRBuilderBase & builder,LLVM::ModuleTranslation & moduleTranslation) const679f6c0056SKolya Panchenko convertOperation(Operation *op, llvm::IRBuilderBase &builder,
689f6c0056SKolya Panchenko LLVM::ModuleTranslation &moduleTranslation) const final {
699f6c0056SKolya Panchenko Operation &opInst = *op;
709f6c0056SKolya Panchenko #include "mlir/Dialect/LLVMIR/VCIXConversions.inc"
719f6c0056SKolya Panchenko
729f6c0056SKolya Panchenko return failure();
739f6c0056SKolya Panchenko }
749f6c0056SKolya Panchenko };
759f6c0056SKolya Panchenko } // namespace
769f6c0056SKolya Panchenko
registerVCIXDialectTranslation(DialectRegistry & registry)779f6c0056SKolya Panchenko void mlir::registerVCIXDialectTranslation(DialectRegistry ®istry) {
789f6c0056SKolya Panchenko registry.insert<vcix::VCIXDialect>();
799f6c0056SKolya Panchenko registry.addExtension(+[](MLIRContext *ctx, vcix::VCIXDialect *dialect) {
809f6c0056SKolya Panchenko dialect->addInterfaces<VCIXDialectLLVMIRTranslationInterface>();
819f6c0056SKolya Panchenko });
829f6c0056SKolya Panchenko }
839f6c0056SKolya Panchenko
registerVCIXDialectTranslation(MLIRContext & context)849f6c0056SKolya Panchenko void mlir::registerVCIXDialectTranslation(MLIRContext &context) {
859f6c0056SKolya Panchenko DialectRegistry registry;
869f6c0056SKolya Panchenko registerVCIXDialectTranslation(registry);
879f6c0056SKolya Panchenko context.appendDialectRegistry(registry);
889f6c0056SKolya Panchenko }
89