xref: /llvm-project/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td (revision 64d514a2e1f1396d54bca0597b1e8b4e580bfd7b)
1//===-- VCIX.td - VCIX dialect operation definitions *- tablegen -*--------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// The file defines the basic operations for the VCIX dialect.
9//
10// The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
11// to extend application processors with custom coprocessors and
12// variable-latency arithmetic units. The interface offers throughput comparable
13// to that of standard RISC-V vector instructions. To accelerate performance,
14// system designers may use VCIX as a low-latency, high-throughput interface to
15// a coprocessor
16//
17// https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef VCIXIR_OPS
22
23include "mlir/IR/OpBase.td"
24include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
25
26//===----------------------------------------------------------------------===//
27// VCIX dialect definition.
28//===----------------------------------------------------------------------===//
29
30def VCIX_Dialect : Dialect {
31  let name = "vcix";
32  let cppNamespace = "::mlir::vcix";
33  let dependentDialects = ["LLVM::LLVMDialect"];
34  let description = [{
35     The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
36     to extend application processors with custom coprocessors and
37     variable-latency arithmetic units. The interface offers throughput comparable
38     to that of standard RISC-V vector instructions. To accelerate performance,
39     system designers may use VCIX as a low-latency, high-throughput interface to
40     a coprocessor
41
42     https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
43  }];
44}
45
46// Special version for intrinsic version where int attr is zext to i32 or i64
47// depending on xlen of the target.
48def VCIX_VectorOrScalar
49    : AnyTypeOf<[LLVM_AnyVector, I<64>, I<32>, F<16>, F<32>, F<64>]>;
50def VCIX_OpcodeAttr : AnyAttrOf<[I32Attr, I64Attr]>;
51def VCIX_Register : AnyTypeOf<[I32, I64]>;
52def VCIX_ImmAttr : AnyAttrOf<[I32Attr, I64Attr]>;
53def VCIX_VL : AnyTypeOf<[I<64>, I<32>]>;
54
55class VCIX_Op<string mnemonic, list<Trait> traits = []>
56    : LLVM_OpBase<VCIX_Dialect, mnemonic, traits> {
57}
58
59def VCIX_BinaryImmOp : VCIX_Op<"v.iv">,
60    Results<(outs LLVM_AnyVector: $res)>,
61    Arguments<(ins VCIX_OpcodeAttr: $opcode,
62                   LLVM_AnyVector: $vs2,
63                   VCIX_ImmAttr: $imm,
64                   Optional<VCIX_VL>: $vl)> {
65  let summary = "Binary VCIX operation with an immediate second operand";
66  let description = [{
67    Binary VCIX operation with an immediate second operand.
68
69    Correponds to:
70    |Mnemonic|funct6|vm|rs2|rs1|funct3|rd|Destination|Sources|
71    |--|--|--|--|--|--|--|--|--|
72    |sf.vc.v.iv|0010--|0|vs2|simm|011|vd|vector vd| simm[4:0]  vector vs2|
73  }];
74
75  string llvmBuilder = [{
76      llvm::Type *xlen =getXlenType($opcode, moduleTranslation);
77      llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
78          xlen, $opcode, $_location, moduleTranslation);
79      llvm::Value *immConst = mlir::LLVM::detail::getLLVMConstant(
80          xlen, $imm, $_location, moduleTranslation);
81      VectorType vt = mlir::cast<VectorType>(op.getResult().getType());
82      llvm::Value *vl =
83          createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
84      $res = createIntrinsicCall(
85          builder, llvm::Intrinsic::riscv_sf_vc_v_iv_se,
86          {opcodeConst, $vs2, immConst, vl},
87          {$_resultType, xlen, $vs2->getType(), xlen, xlen});
88  }];
89}
90
91def VCIX_BinaryOp : VCIX_Op<"v.sv">,
92    Results<(outs LLVM_AnyVector: $res)>,
93    Arguments<(ins VCIX_OpcodeAttr: $opcode,
94                   LLVM_AnyVector: $vs2,
95                   VCIX_VectorOrScalar: $op,
96                   Optional<VCIX_VL>: $vl)> {
97  let summary = "Binary VCIX operation";
98  let description = [{
99    Binary VCIX operation with an integer scalar, or floating pointer scalar or
100    vector second operand.
101
102    Correponds to:
103    |Mnemonic|funct6|vm|rs2|rs1|funct3|rd|Destination| Sources|
104    |--|--|--|--|--|--|--|--|--|--|
105    |sf.vc.v.vv|0010--|0|vs2|vs1|000|vd|vector vd|vector vs1, vector vs|
106    |sf.vc.v.xv|0010--|0|vs2|xs1|100|vd|vector vd|scalar xs1, vector vs2|
107    |sf.vc.v.fv|0010--|0|vs2|fs1|101|vd|vector vd|scalar fs1, vector vs2|
108  }];
109
110  string llvmBuilder = [{
111      llvm::Type *xlen = getXlenType($opcode, moduleTranslation);
112      llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
113          xlen, $opcode, $_location, moduleTranslation);
114      llvm::Intrinsic::ID id;
115      llvm::Type *opType = $op->getType();
116      if (opType->isVectorTy()) {
117        id = llvm::Intrinsic::riscv_sf_vc_v_vv_se;
118      } else if (opType->isIntegerTy()) {
119        id = llvm::Intrinsic::riscv_sf_vc_v_xv_se;
120      } else {
121        id = llvm::Intrinsic::riscv_sf_vc_v_fv_se;
122      }
123      VectorType vt = mlir::cast<VectorType>(op.getResult().getType());
124      llvm::Value *vl =
125          createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
126      $res = createIntrinsicCall(
127          builder, id, {opcodeConst, $vs2, $op, vl},
128          {$_resultType, xlen, $vs2->getType(), $op->getType(), xlen});
129  }];
130}
131
132#endif // VCIXIR_OPS
133