[OptTable] Fix typo VALUE => VALUES (NFCI) (#121523)
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInstrInfoZb.td
blob124caa3b69d31e69eab513820c71889d6cebe981
1 //===-- RISCVInstrInfoZb.td - RISC-V Bitmanip instructions -*- 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 //
9 // This file describes the RISC-V instructions from the standard Bitmanip
10 // extensions, versions:
11 //   Zba - 1.0
12 //   Zbb - 1.0
13 //   Zbc - 1.0
14 //   Zbs - 1.0
16 // This file also describes RISC-V instructions from the Zbk* extensions in
17 // Cryptography Extensions Volume I: Scalar & Entropy Source Instructions,
18 // versions:
19 //   Zbkb - 1.0
20 //   Zbkc - 1.0
21 //   Zbkx - 1.0
23 //===----------------------------------------------------------------------===//
25 //===----------------------------------------------------------------------===//
26 // Operand and SDNode transformation definitions.
27 //===----------------------------------------------------------------------===//
29 def SDTIntShiftAddOp : SDTypeProfile<1, 3, [   // shl_add
30   SDTCisSameAs<0, 1>, SDTCisSameAs<0, 3>, SDTCisInt<0>, SDTCisInt<2>,
31   SDTCisInt<3>
32 ]>;
34 def riscv_shl_add : SDNode<"RISCVISD::SHL_ADD", SDTIntShiftAddOp>;
35 def riscv_clzw    : SDNode<"RISCVISD::CLZW",    SDT_RISCVIntUnaryOpW>;
36 def riscv_ctzw    : SDNode<"RISCVISD::CTZW",    SDT_RISCVIntUnaryOpW>;
37 def riscv_rolw    : SDNode<"RISCVISD::ROLW",    SDT_RISCVIntBinOpW>;
38 def riscv_rorw    : SDNode<"RISCVISD::RORW",    SDT_RISCVIntBinOpW>;
39 def riscv_brev8   : SDNode<"RISCVISD::BREV8",   SDTIntUnaryOp>;
40 def riscv_orc_b   : SDNode<"RISCVISD::ORC_B",   SDTIntUnaryOp>;
41 def riscv_zip     : SDNode<"RISCVISD::ZIP",     SDTIntUnaryOp>;
42 def riscv_unzip   : SDNode<"RISCVISD::UNZIP",   SDTIntUnaryOp>;
43 def riscv_absw    : SDNode<"RISCVISD::ABSW",    SDTIntUnaryOp>;
44 def riscv_clmul   : SDNode<"RISCVISD::CLMUL",   SDTIntBinOp>;
45 def riscv_clmulh  : SDNode<"RISCVISD::CLMULH",  SDTIntBinOp>;
46 def riscv_clmulr  : SDNode<"RISCVISD::CLMULR",  SDTIntBinOp>;
48 def BCLRXForm : SDNodeXForm<imm, [{
49   // Find the lowest 0.
50   return CurDAG->getTargetConstant(llvm::countr_one(N->getZExtValue()),
51                                    SDLoc(N), N->getValueType(0));
52 }]>;
54 def SingleBitSetMaskToIndex : SDNodeXForm<imm, [{
55   // Find the lowest 1.
56   return CurDAG->getTargetConstant(llvm::countr_zero(N->getZExtValue()),
57                                    SDLoc(N), N->getValueType(0));
58 }]>;
60 // Checks if this mask has a single 0 bit and cannot be used with ANDI.
61 def BCLRMask : ImmLeaf<XLenVT, [{
62   if (Subtarget->is64Bit())
63     return !isInt<12>(Imm) && isPowerOf2_64(~Imm);
64   return !isInt<12>(Imm) && isPowerOf2_32(~Imm);
65 }], BCLRXForm>;
67 // Checks if this mask has a single 1 bit and cannot be used with ORI/XORI.
68 def SingleBitSetMask : ImmLeaf<XLenVT, [{
69   if (Subtarget->is64Bit())
70     return !isInt<12>(Imm) && isPowerOf2_64(Imm);
71   return !isInt<12>(Imm) && isPowerOf2_32(Imm);
72 }], SingleBitSetMaskToIndex>;
74 // Check if (or r, i) can be optimized to (BSETI (BSETI r, i0), i1),
75 // in which i = (1 << i0) | (1 << i1).
76 def BSETINVTwoBitsMask : PatLeaf<(imm), [{
77   if (!N->hasOneUse())
78     return false;
79   // The immediate should not be a simm12.
80   if (isInt<12>(N->getSExtValue()))
81     return false;
82   // The immediate must have exactly two bits set.
83   return llvm::popcount(N->getZExtValue()) == 2;
84 }]>;
86 def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{
87   uint64_t I = N->getZExtValue();
88   return CurDAG->getTargetConstant(llvm::Log2_64(I), SDLoc(N),
89                                    N->getValueType(0));
90 }]>;
92 // Check if (or r, imm) can be optimized to (BSETI (ORI r, i0), i1),
93 // in which imm = i0 | (1 << i1).
94 def BSETINVORIMask : PatLeaf<(imm), [{
95   if (!N->hasOneUse())
96     return false;
97   // The immediate should not be a simm12.
98   if (isInt<12>(N->getSExtValue()))
99     return false;
100   // There should be only one set bit from bit 11 to the top.
101   return isPowerOf2_64(N->getZExtValue() & ~0x7ff);
102 }]>;
104 def BSETINVORIMaskLow : SDNodeXForm<imm, [{
105   return CurDAG->getTargetConstant(N->getZExtValue() & 0x7ff,
106                                    SDLoc(N), N->getValueType(0));
107 }]>;
109 // Check if (and r, i) can be optimized to (BCLRI (BCLRI r, i0), i1),
110 // in which i = ~((1<<i0) | (1<<i1)).
111 def BCLRITwoBitsMask : PatLeaf<(imm), [{
112   if (!N->hasOneUse())
113     return false;
114   // The immediate should not be a simm12.
115   if (isInt<12>(N->getSExtValue()))
116     return false;
117   // The immediate must have exactly two bits clear.
118   return (unsigned)llvm::popcount(N->getZExtValue()) == Subtarget->getXLen() - 2;
119 }]>;
121 def BCLRITwoBitsMaskLow : SDNodeXForm<imm, [{
122   return CurDAG->getTargetConstant(llvm::countr_zero(~N->getZExtValue()),
123                                    SDLoc(N), N->getValueType(0));
124 }]>;
126 def BCLRITwoBitsMaskHigh : SDNodeXForm<imm, [{
127   uint64_t I = N->getZExtValue();
128   if (!Subtarget->is64Bit())
129     I |= maskLeadingOnes<uint64_t>(32);
130   return CurDAG->getTargetConstant(llvm::Log2_64(~I), SDLoc(N),
131                                    N->getValueType(0));
132 }]>;
134 // Check if (and r, i) can be optimized to (BCLRI (ANDI r, i0), i1),
135 // in which i = i0 & ~(1<<i1).
136 def BCLRIANDIMask : PatLeaf<(imm), [{
137   if (!N->hasOneUse())
138     return false;
139   // The immediate should not be a simm12.
140   if (isInt<12>(N->getSExtValue()))
141     return false;
142   // There should be only one clear bit from bit 11 to the top.
143   uint64_t I = N->getZExtValue() | 0x7ff;
144   return Subtarget->is64Bit() ? isPowerOf2_64(~I) : isPowerOf2_32(~I);
145 }]>;
147 def BCLRIANDIMaskLow : SDNodeXForm<imm, [{
148   return CurDAG->getSignedTargetConstant((N->getZExtValue() & 0x7ff) | ~0x7ffull,
149                                          SDLoc(N), N->getValueType(0));
150 }]>;
152 def SimmShiftRightBy2XForm : SDNodeXForm<imm, [{
153   return CurDAG->getSignedTargetConstant(N->getSExtValue() >> 2, SDLoc(N),
154                                          N->getValueType(0));
155 }]>;
157 def SimmShiftRightBy3XForm : SDNodeXForm<imm, [{
158   return CurDAG->getSignedTargetConstant(N->getSExtValue() >> 3, SDLoc(N),
159                                          N->getValueType(0));
160 }]>;
162 def CSImm12MulBy4 : PatLeaf<(imm), [{
163   if (!N->hasOneUse())
164     return false;
165   int64_t C = N->getSExtValue();
166   // Skip if C is simm12, an lui, or can be optimized by the PatLeaf AddiPair.
167   return !isInt<13>(C) && !isShiftedInt<20, 12>(C) && isShiftedInt<12, 2>(C);
168 }], SimmShiftRightBy2XForm>;
170 def CSImm12MulBy8 : PatLeaf<(imm), [{
171   if (!N->hasOneUse())
172     return false;
173   int64_t C = N->getSExtValue();
174   // Skip if C is simm12, an lui or can be optimized by the PatLeaf AddiPair or
175   // CSImm12MulBy4.
176   return !isInt<14>(C) && !isShiftedInt<20, 12>(C) && isShiftedInt<12, 3>(C);
177 }], SimmShiftRightBy3XForm>;
179 // Pattern to exclude simm12 immediates from matching, namely `non_imm12`.
180 // GISel currently doesn't support PatFrag for leaf nodes, so `non_imm12`
181 // cannot be implemented in that way. To reuse patterns between the two
182 // ISels, we instead create PatFrag on operators that use `non_imm12`.
183 class binop_with_non_imm12<SDPatternOperator binop>
184   : PatFrag<(ops node:$x, node:$y), (binop node:$x, node:$y), [{
185   auto *C = dyn_cast<ConstantSDNode>(Operands[1]);
186   return !C || !isInt<12>(C->getSExtValue());
187 }]> {
188   let PredicateCodeUsesOperands = 1;
189   let GISelPredicateCode = [{
190     const MachineOperand &ImmOp = *Operands[1];
192     if (ImmOp.isReg() && ImmOp.getReg())
193       if (auto Val = getIConstantVRegValWithLookThrough(ImmOp.getReg(), MRI)) {
194         // We do NOT want immediates that fit in 12 bits.
195         return !isInt<12>(Val->Value.getSExtValue());
196       }
198     return true;
199   }];
201 def add_non_imm12       : binop_with_non_imm12<add>;
202 def add_like_non_imm12 : binop_with_non_imm12<add_like>;
204 def Shifted32OnesMask : IntImmLeaf<XLenVT, [{
205   if (!Imm.isShiftedMask())
206     return false;
208   unsigned TrailingZeros = Imm.countr_zero();
209   return TrailingZeros > 0 && TrailingZeros < 32 &&
210          Imm == UINT64_C(0xFFFFFFFF) << TrailingZeros;
211 }], TrailingZeros>;
213 def sh1add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<1>", [], [], 6>;
214 def sh2add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<2>", [], [], 6>;
215 def sh3add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<3>", [], [], 6>;
216 def gi_sh1add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<1>">,
217                    GIComplexPatternEquiv<sh1add_op>;
218 def gi_sh2add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<2>">,
219                    GIComplexPatternEquiv<sh2add_op>;
220 def gi_sh3add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<3>">,
221                    GIComplexPatternEquiv<sh3add_op>;
224 def sh1add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<1>", [], [], 6>;
225 def sh2add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<2>", [], [], 6>;
226 def sh3add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<3>", [], [], 6>;
227 def gi_sh1add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<1>">,
228                       GIComplexPatternEquiv<sh1add_uw_op>;
229 def gi_sh2add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<2>">,
230                       GIComplexPatternEquiv<sh2add_uw_op>;
231 def gi_sh3add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<3>">,
232                       GIComplexPatternEquiv<sh3add_uw_op>;
234 //===----------------------------------------------------------------------===//
235 // Instruction class templates
236 //===----------------------------------------------------------------------===//
238 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
239 class RVBUnaryR<bits<7> funct7, bits<3> funct3,
240                 RISCVOpcode opcode, string opcodestr>
241     : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
242               opcodestr, "$rd, $rs1"> {
243   let rs2 = 0;
246 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
247 class RVBShift_ri<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
248                   string opcodestr>
249     : RVInstIShift<imm11_7, funct3, opcode, (outs GPR:$rd),
250                    (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
251                    "$rd, $rs1, $shamt">;
253 //===----------------------------------------------------------------------===//
254 // Instructions
255 //===----------------------------------------------------------------------===//
257 let Predicates = [HasStdExtZbbOrZbkb] in {
258 def ANDN  : ALU_rr<0b0100000, 0b111, "andn">,
259             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
260 def ORN   : ALU_rr<0b0100000, 0b110, "orn">,
261             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
262 def XNOR  : ALU_rr<0b0100000, 0b100, "xnor">,
263             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
264 } // Predicates = [HasStdExtZbbOrZbkb]
266 let Predicates = [HasStdExtZba] in {
267 def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,
268              Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
269 def SH2ADD : ALU_rr<0b0010000, 0b100, "sh2add">,
270              Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
271 def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,
272              Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
273 } // Predicates = [HasStdExtZba]
275 let Predicates = [HasStdExtZba, IsRV64] in {
276 def SLLI_UW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,
277               Sched<[WriteShiftImm32, ReadShiftImm32]>;
278 def ADD_UW : ALUW_rr<0b0000100, 0b000, "add.uw">,
279              Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
280 def SH1ADD_UW : ALUW_rr<0b0010000, 0b010, "sh1add.uw">,
281                 Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
282 def SH2ADD_UW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,
283                 Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
284 def SH3ADD_UW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,
285                 Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
286 } // Predicates = [HasStdExtZba, IsRV64]
288 let Predicates = [HasStdExtZbbOrZbkb] in {
289 def ROL   : ALU_rr<0b0110000, 0b001, "rol">,
290             Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
291 def ROR   : ALU_rr<0b0110000, 0b101, "ror">,
292             Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
294 def RORI  : Shift_ri<0b01100, 0b101, "rori">,
295             Sched<[WriteRotateImm, ReadRotateImm]>;
296 } // Predicates = [HasStdExtZbbOrZbkb]
298 let Predicates = [HasStdExtZbbOrZbkb, IsRV64], IsSignExtendingOpW = 1 in {
299 def ROLW  : ALUW_rr<0b0110000, 0b001, "rolw">,
300             Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
301 def RORW  : ALUW_rr<0b0110000, 0b101, "rorw">,
302             Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
304 def RORIW : ShiftW_ri<0b0110000, 0b101, "roriw">,
305             Sched<[WriteRotateImm32, ReadRotateImm32]>;
306 } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
308 let Predicates = [HasStdExtZbs] in {
309 def BCLR : ALU_rr<0b0100100, 0b001, "bclr">,
310            Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
311 def BSET : ALU_rr<0b0010100, 0b001, "bset">,
312            Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
313 def BINV : ALU_rr<0b0110100, 0b001, "binv">,
314            Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
315 let IsSignExtendingOpW = 1 in
316 def BEXT : ALU_rr<0b0100100, 0b101, "bext">,
317            Sched<[WriteBEXT, ReadSingleBit, ReadSingleBit]>;
319 def BCLRI : Shift_ri<0b01001, 0b001, "bclri">,
320             Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
321 def BSETI : Shift_ri<0b00101, 0b001, "bseti">,
322             Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
323 def BINVI : Shift_ri<0b01101, 0b001, "binvi">,
324             Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
325 let IsSignExtendingOpW = 1 in
326 def BEXTI : Shift_ri<0b01001, 0b101, "bexti">,
327             Sched<[WriteBEXTI, ReadSingleBitImm]>;
328 } // Predicates = [HasStdExtZbs]
330 // These instructions were named xperm.n and xperm.b in the last version of
331 // the draft bit manipulation specification they were included in. However, we
332 // use the mnemonics given to them in the ratified Zbkx extension.
333 let Predicates = [HasStdExtZbkx] in {
334 def XPERM4 : ALU_rr<0b0010100, 0b010, "xperm4">,
335              Sched<[WriteXPERM, ReadXPERM, ReadXPERM]>;
336 def XPERM8 : ALU_rr<0b0010100, 0b100, "xperm8">,
337              Sched<[WriteXPERM, ReadXPERM, ReadXPERM]>;
338 } // Predicates = [HasStdExtZbkx]
340 let Predicates = [HasStdExtZbb], IsSignExtendingOpW = 1 in {
341 def CLZ  : Unary_r<0b011000000000, 0b001, "clz">,
342            Sched<[WriteCLZ, ReadCLZ]>;
343 def CTZ  : Unary_r<0b011000000001, 0b001, "ctz">,
344            Sched<[WriteCTZ, ReadCTZ]>;
345 def CPOP : Unary_r<0b011000000010, 0b001, "cpop">,
346            Sched<[WriteCPOP, ReadCPOP]>;
347 } // Predicates = [HasStdExtZbb]
349 let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {
350 def CLZW  : UnaryW_r<0b011000000000, 0b001, "clzw">,
351             Sched<[WriteCLZ32, ReadCLZ32]>;
352 def CTZW  : UnaryW_r<0b011000000001, 0b001, "ctzw">,
353             Sched<[WriteCTZ32, ReadCTZ32]>;
354 def CPOPW : UnaryW_r<0b011000000010, 0b001, "cpopw">,
355             Sched<[WriteCPOP32, ReadCPOP32]>;
356 } // Predicates = [HasStdExtZbb, IsRV64]
358 let Predicates = [HasStdExtZbb], IsSignExtendingOpW = 1 in {
359 def SEXT_B : Unary_r<0b011000000100, 0b001, "sext.b">,
360              Sched<[WriteIALU, ReadIALU]>;
361 def SEXT_H : Unary_r<0b011000000101, 0b001, "sext.h">,
362              Sched<[WriteIALU, ReadIALU]>;
363 } // Predicates = [HasStdExtZbb]
365 let Predicates = [HasStdExtZbc] in {
366 def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr", Commutable=1>,
367              Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
368 } // Predicates = [HasStdExtZbc]
370 let Predicates = [HasStdExtZbcOrZbkc] in {
371 def CLMUL  : ALU_rr<0b0000101, 0b001, "clmul", Commutable=1>,
372              Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
373 def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh", Commutable=1>,
374              Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
375 } // Predicates = [HasStdExtZbcOrZbkc]
377 let Predicates = [HasStdExtZbb] in {
378 def MIN  : ALU_rr<0b0000101, 0b100, "min", Commutable=1>,
379            Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;
380 def MINU : ALU_rr<0b0000101, 0b101, "minu", Commutable=1>,
381            Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;
382 def MAX  : ALU_rr<0b0000101, 0b110, "max", Commutable=1>,
383            Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;
384 def MAXU : ALU_rr<0b0000101, 0b111, "maxu", Commutable=1>,
385            Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;
386 } // Predicates = [HasStdExtZbb]
388 let Predicates = [HasStdExtZbkb] in {
389 def PACK  : ALU_rr<0b0000100, 0b100, "pack">,
390             Sched<[WritePACK, ReadPACK, ReadPACK]>;
391 let IsSignExtendingOpW = 1 in
392 def PACKH : ALU_rr<0b0000100, 0b111, "packh">,
393             Sched<[WritePACK, ReadPACK, ReadPACK]>;
394 } // Predicates = [HasStdExtZbkb]
396 let Predicates = [HasStdExtZbkb, IsRV64], IsSignExtendingOpW = 1 in
397 def PACKW  : ALUW_rr<0b0000100, 0b100, "packw">,
398              Sched<[WritePACK32, ReadPACK32, ReadPACK32]>;
400 let Predicates = [HasStdExtZbb, IsRV32] in {
401 def ZEXT_H_RV32 : RVBUnaryR<0b0000100, 0b100, OPC_OP, "zext.h">,
402                   Sched<[WriteIALU, ReadIALU]>;
403 } // Predicates = [HasStdExtZbb, IsRV32]
405 let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {
406 def ZEXT_H_RV64 : RVBUnaryR<0b0000100, 0b100, OPC_OP_32, "zext.h">,
407                   Sched<[WriteIALU, ReadIALU]>;
408 } // Predicates = [HasStdExtZbb, IsRV64]
410 let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
411 def REV8_RV32 : Unary_r<0b011010011000, 0b101, "rev8">,
412                 Sched<[WriteREV8, ReadREV8]>;
413 } // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
415 let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
416 def REV8_RV64 : Unary_r<0b011010111000, 0b101, "rev8">,
417                 Sched<[WriteREV8, ReadREV8]>;
418 } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
420 let Predicates = [HasStdExtZbb] in {
421 def ORC_B : Unary_r<0b001010000111, 0b101, "orc.b">,
422             Sched<[WriteORCB, ReadORCB]>;
423 } // Predicates = [HasStdExtZbb]
425 let Predicates = [HasStdExtZbkb] in
426 def BREV8 : Unary_r<0b011010000111, 0b101, "brev8">,
427             Sched<[WriteBREV8, ReadBREV8]>;
429 let Predicates = [HasStdExtZbkb, IsRV32] in {
430 def ZIP_RV32   : Unary_r<0b000010001111, 0b001, "zip">,
431                  Sched<[WriteZIP, ReadZIP]>;
432 def UNZIP_RV32 : Unary_r<0b000010001111, 0b101, "unzip">,
433                  Sched<[WriteZIP, ReadZIP]>;
434 } // Predicates = [HasStdExtZbkb, IsRV32]
437 //===----------------------------------------------------------------------===//
438 // Pseudo Instructions
439 //===----------------------------------------------------------------------===//
441 let Predicates = [HasStdExtZba, IsRV64] in {
442 def : InstAlias<"zext.w $rd, $rs", (ADD_UW GPR:$rd, GPR:$rs, X0)>;
443 } // Predicates = [HasStdExtZba, IsRV64]
445 let Predicates = [HasStdExtZbb] in {
446 def : InstAlias<"ror $rd, $rs1, $shamt",
447                 (RORI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
448 } // Predicates = [HasStdExtZbb]
450 let Predicates = [HasStdExtZbb, IsRV64] in {
451 def : InstAlias<"rorw $rd, $rs1, $shamt",
452                 (RORIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
453 } // Predicates = [HasStdExtZbb, IsRV64]
455 let Predicates = [HasStdExtZbs] in {
456 def : InstAlias<"bset $rd, $rs1, $shamt",
457                 (BSETI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
458 def : InstAlias<"bclr $rd, $rs1, $shamt",
459                 (BCLRI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
460 def : InstAlias<"binv $rd, $rs1, $shamt",
461                 (BINVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
462 def : InstAlias<"bext $rd, $rs1, $shamt",
463                 (BEXTI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
464 } // Predicates = [HasStdExtZbs]
466 let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in {
467 def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;
468 } // Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32]
470 let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in {
471 def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>;
472 } // Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64]
474 //===----------------------------------------------------------------------===//
475 // Codegen patterns
476 //===----------------------------------------------------------------------===//
478 def invLogicImm : ComplexPattern<XLenVT, 1, "selectInvLogicImm", [], [], 0>;
480 let Predicates = [HasStdExtZbbOrZbkb] in {
481 def : Pat<(XLenVT (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
482 def : Pat<(XLenVT (or  GPR:$rs1, (not GPR:$rs2))), (ORN  GPR:$rs1, GPR:$rs2)>;
483 def : Pat<(XLenVT (xor GPR:$rs1, (not GPR:$rs2))), (XNOR GPR:$rs1, GPR:$rs2)>;
485 def : Pat<(XLenVT (and GPR:$rs1, invLogicImm:$rs2)), (ANDN GPR:$rs1, invLogicImm:$rs2)>;
486 def : Pat<(XLenVT (or  GPR:$rs1, invLogicImm:$rs2)), (ORN  GPR:$rs1, invLogicImm:$rs2)>;
487 def : Pat<(XLenVT (xor GPR:$rs1, invLogicImm:$rs2)), (XNOR GPR:$rs1, invLogicImm:$rs2)>;
488 } // Predicates = [HasStdExtZbbOrZbkb]
490 let Predicates = [HasStdExtZbbOrZbkb] in {
491 def : PatGprGpr<shiftop<rotl>, ROL>;
492 def : PatGprGpr<shiftop<rotr>, ROR>;
494 def : PatGprImm<rotr, RORI, uimmlog2xlen>;
495 // There's no encoding for roli in the the 'B' extension as it can be
496 // implemented with rori by negating the immediate.
497 def : Pat<(XLenVT (rotl GPR:$rs1, uimmlog2xlen:$shamt)),
498           (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
499 } // Predicates = [HasStdExtZbbOrZbkb]
501 let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
502 def : PatGprGpr<shiftopw<riscv_rolw>, ROLW>;
503 def : PatGprGpr<shiftopw<riscv_rorw>, RORW>;
504 def : PatGprImm<riscv_rorw, RORIW, uimm5>;
505 def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
506           (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
507 } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
509 let Predicates = [HasStdExtZbs] in {
510 def : Pat<(XLenVT (and (not (shiftop<shl> 1, (XLenVT GPR:$rs2))), GPR:$rs1)),
511           (BCLR GPR:$rs1, GPR:$rs2)>;
512 def : Pat<(XLenVT (and (rotl -2, (XLenVT GPR:$rs2)), GPR:$rs1)),
513           (BCLR GPR:$rs1, GPR:$rs2)>;
514 def : Pat<(XLenVT (or (shiftop<shl> 1, (XLenVT GPR:$rs2)), GPR:$rs1)),
515           (BSET GPR:$rs1, GPR:$rs2)>;
516 def : Pat<(XLenVT (xor (shiftop<shl> 1, (XLenVT GPR:$rs2)), GPR:$rs1)),
517           (BINV GPR:$rs1, GPR:$rs2)>;
518 def : Pat<(XLenVT (and (shiftop<srl> GPR:$rs1, (XLenVT GPR:$rs2)), 1)),
519           (BEXT GPR:$rs1, GPR:$rs2)>;
521 def : Pat<(XLenVT (shiftop<shl> 1, (XLenVT GPR:$rs2))),
522           (BSET (XLenVT X0), GPR:$rs2)>;
523 def : Pat<(XLenVT (not (shiftop<shl> -1, (XLenVT GPR:$rs2)))),
524           (ADDI (XLenVT (BSET (XLenVT X0), GPR:$rs2)), -1)>;
526 def : Pat<(XLenVT (and GPR:$rs1, BCLRMask:$mask)),
527           (BCLRI GPR:$rs1, BCLRMask:$mask)>;
528 def : Pat<(XLenVT (or GPR:$rs1, SingleBitSetMask:$mask)),
529           (BSETI GPR:$rs1, SingleBitSetMask:$mask)>;
530 def : Pat<(XLenVT (xor GPR:$rs1, SingleBitSetMask:$mask)),
531           (BINVI GPR:$rs1, SingleBitSetMask:$mask)>;
533 def : Pat<(XLenVT (and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1))),
534           (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
536 def : Pat<(XLenVT (seteq (XLenVT (and GPR:$rs1, SingleBitSetMask:$mask)), 0)),
537           (BEXTI (XLenVT (XORI GPR:$rs1, -1)), SingleBitSetMask:$mask)>;
539 def : Pat<(XLenVT (or GPR:$r, BSETINVTwoBitsMask:$i)),
540           (BSETI (XLenVT (BSETI GPR:$r, (TrailingZeros BSETINVTwoBitsMask:$i))),
541                  (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
542 def : Pat<(XLenVT (xor GPR:$r, BSETINVTwoBitsMask:$i)),
543           (BINVI (XLenVT (BINVI GPR:$r, (TrailingZeros BSETINVTwoBitsMask:$i))),
544                  (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
545 def : Pat<(XLenVT (or GPR:$r, BSETINVORIMask:$i)),
546           (BSETI (XLenVT (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i))),
547                  (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
548 def : Pat<(XLenVT (xor GPR:$r, BSETINVORIMask:$i)),
549           (BINVI (XLenVT (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i))),
550                  (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
551 def : Pat<(XLenVT (and GPR:$r, BCLRITwoBitsMask:$i)),
552           (BCLRI (XLenVT (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i))),
553                  (BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;
554 def : Pat<(XLenVT (and GPR:$r, BCLRIANDIMask:$i)),
555           (BCLRI (XLenVT (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i))),
556                  (BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
557 } // Predicates = [HasStdExtZbs]
559 let Predicates = [HasStdExtZbb] in
560 def : PatGpr<riscv_orc_b, ORC_B>;
562 let Predicates = [HasStdExtZbkb] in
563 def : PatGpr<riscv_brev8, BREV8>;
565 let Predicates = [HasStdExtZbkb, IsRV32] in {
566 // We treat zip and unzip as separate instructions, so match it directly.
567 def : PatGpr<riscv_zip, ZIP_RV32, i32>;
568 def : PatGpr<riscv_unzip, UNZIP_RV32, i32>;
569 } // Predicates = [HasStdExtZbkb, IsRV32]
571 let Predicates = [HasStdExtZbb] in {
572 def : PatGpr<ctlz, CLZ>;
573 def : PatGpr<cttz, CTZ>;
574 def : PatGpr<ctpop, CPOP>;
575 } // Predicates = [HasStdExtZbb]
577 let Predicates = [HasStdExtZbb, IsRV64] in {
578 def : PatGpr<riscv_clzw, CLZW>;
579 def : PatGpr<riscv_ctzw, CTZW>;
580 def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
582 def : Pat<(i64 (riscv_absw GPR:$rs1)),
583           (MAX GPR:$rs1, (XLenVT (SUBW (XLenVT X0), GPR:$rs1)))>;
584 } // Predicates = [HasStdExtZbb, IsRV64]
586 let Predicates = [HasStdExtZbb] in {
587 def : Pat<(XLenVT (sext_inreg GPR:$rs1, i8)), (SEXT_B GPR:$rs1)>;
588 def : Pat<(XLenVT (sext_inreg GPR:$rs1, i16)), (SEXT_H GPR:$rs1)>;
589 } // Predicates = [HasStdExtZbb]
591 let Predicates = [HasStdExtZbb] in {
592 def : PatGprGpr<smin, MIN>;
593 def : PatGprGpr<smax, MAX>;
594 def : PatGprGpr<umin, MINU>;
595 def : PatGprGpr<umax, MAXU>;
596 } // Predicates = [HasStdExtZbb]
598 let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in
599 def : PatGpr<bswap, REV8_RV32, i32>;
601 let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in
602 def : PatGpr<bswap, REV8_RV64, i64>;
604 let Predicates = [HasStdExtZbkb] in {
605 def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
606               (zexti8 (XLenVT GPR:$rs1))),
607           (PACKH GPR:$rs1, GPR:$rs2)>;
608 def : Pat<(or (shl (zexti8 (XLenVT GPR:$rs2)), (XLenVT 8)),
609               (zexti8 (XLenVT GPR:$rs1))),
610           (PACKH GPR:$rs1, GPR:$rs2)>;
611 def : Pat<(and (or (shl GPR:$rs2, (XLenVT 8)),
612                    (zexti8 (XLenVT GPR:$rs1))), 0xFFFF),
613           (PACKH GPR:$rs1, GPR:$rs2)>;
614 def : Pat<(or (shl (zexti8 (XLenVT GPR:$rs2)), (XLenVT 24)),
615               (shl (zexti8 (XLenVT GPR:$rs1)), (XLenVT 16))),
616           (SLLI (XLenVT (PACKH GPR:$rs1, GPR:$rs2)), (XLenVT 16))>;
618 def : Pat<(binop_allhusers<or> (shl GPR:$rs2, (XLenVT 8)),
619                                (zexti8 (XLenVT GPR:$rs1))),
620           (PACKH GPR:$rs1, GPR:$rs2)>;
621 } // Predicates = [HasStdExtZbkb]
623 let Predicates = [HasStdExtZbkb, IsRV32] in {
624 def : Pat<(i32 (or (zexti16 (i32 GPR:$rs1)), (shl GPR:$rs2, (i32 16)))),
625           (PACK GPR:$rs1, GPR:$rs2)>;
626 def : Pat<(or (or
627                   (shl (zexti8 (XLenVT GPR:$op1rs2)), (XLenVT 24)),
628                   (shl (zexti8 (XLenVT GPR:$op1rs1)), (XLenVT 16))),
629               (or
630                   (shl (zexti8 (XLenVT GPR:$op0rs2)), (XLenVT 8)),
631                   (zexti8 (XLenVT GPR:$op0rs1)))),
632           (PACK (XLenVT (PACKH GPR:$op0rs1, GPR:$op0rs2)),
633                 (XLenVT (PACKH GPR:$op1rs1, GPR:$op1rs2)))>;
636 let Predicates = [HasStdExtZbkb, IsRV64] in {
637 def : Pat<(i64 (or (zexti32 (i64 GPR:$rs1)), (shl GPR:$rs2, (i64 32)))),
638           (PACK GPR:$rs1, GPR:$rs2)>;
640 def : Pat<(binop_allwusers<or> (shl GPR:$rs2, (i64 16)),
641                                (zexti16 (i64 GPR:$rs1))),
642           (PACKW GPR:$rs1, GPR:$rs2)>;
643 def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
644                    (zexti16 (i64 GPR:$rs1)))),
645           (PACKW GPR:$rs1, GPR:$rs2)>;
646 } // Predicates = [HasStdExtZbkb, IsRV64]
648 let Predicates = [HasStdExtZbb, IsRV32] in
649 def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;
650 let Predicates = [HasStdExtZbb, IsRV64] in
651 def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
653 let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in
654 def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (PACK GPR:$rs, (XLenVT X0))>;
655 let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in
656 def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (PACKW GPR:$rs, (XLenVT X0))>;
658 let Predicates = [HasStdExtZba] in {
660 foreach i = {1,2,3} in {
661   defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
662   def : Pat<(XLenVT (add_like_non_imm12 (shl GPR:$rs1, (XLenVT i)), GPR:$rs2)),
663             (shxadd GPR:$rs1, GPR:$rs2)>;
664   def : Pat<(XLenVT (riscv_shl_add GPR:$rs1, (XLenVT i), GPR:$rs2)),
665             (shxadd GPR:$rs1, GPR:$rs2)>;
667   defvar pat = !cast<ComplexPattern>("sh"#i#"add_op");
668   // More complex cases use a ComplexPattern.
669   def : Pat<(XLenVT (add_like_non_imm12 pat:$rs1, GPR:$rs2)),
670             (shxadd pat:$rs1, GPR:$rs2)>;
673 def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),
674           (SH2ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),
675                   GPR:$r)>;
676 def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),
677           (SH3ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),
678                   GPR:$r)>;
680 } // Predicates = [HasStdExtZba]
682 let Predicates = [HasStdExtZba, IsRV64] in {
683 def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
684           (SLLI_UW GPR:$rs1, uimm5:$shamt)>;
685 // Match a shifted 0xffffffff mask. Use SRLI to clear the LSBs and SLLI_UW to
686 // mask and shift.
687 def : Pat<(i64 (and GPR:$rs1, Shifted32OnesMask:$mask)),
688           (SLLI_UW (XLenVT (SRLI GPR:$rs1, Shifted32OnesMask:$mask)),
689                    Shifted32OnesMask:$mask)>;
690 def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),
691           (ADD_UW GPR:$rs1, GPR:$rs2)>;
692 def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADD_UW GPR:$rs, (XLenVT X0))>;
694 foreach i = {1,2,3} in {
695   defvar shxadd_uw = !cast<Instruction>("SH"#i#"ADD_UW");
696   def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)), (XLenVT GPR:$rs2))),
697             (shxadd_uw GPR:$rs1, GPR:$rs2)>;
698   def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),
699             (shxadd_uw GPR:$rs1, GPR:$rs2)>;
702 def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), (XLenVT GPR:$rs2))),
703           (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
704 def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), (XLenVT GPR:$rs2))),
705           (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
706 def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), (XLenVT GPR:$rs2))),
707           (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
709 // More complex cases use a ComplexPattern.
710 foreach i = {1,2,3} in {
711   defvar pat = !cast<ComplexPattern>("sh"#i#"add_uw_op");
712   def : Pat<(i64 (add_like_non_imm12 pat:$rs1, (XLenVT GPR:$rs2))),
713             (!cast<Instruction>("SH"#i#"ADD_UW") pat:$rs1, GPR:$rs2)>;
716 def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE), (XLenVT GPR:$rs2))),
717           (SH1ADD (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;
718 def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC), (XLenVT GPR:$rs2))),
719           (SH2ADD (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;
720 def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8), (XLenVT GPR:$rs2))),
721           (SH3ADD (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
723 // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
724 def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x1FFFFFFFE), (XLenVT GPR:$rs2))),
725           (SH1ADD_UW (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;
726 def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x3FFFFFFFC), (XLenVT GPR:$rs2))),
727           (SH2ADD_UW (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;
728 def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x7FFFFFFF8), (XLenVT GPR:$rs2))),
729           (SH3ADD_UW (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;
731 } // Predicates = [HasStdExtZba, IsRV64]
733 let Predicates = [HasStdExtZbcOrZbkc] in {
734 def : PatGprGpr<riscv_clmul, CLMUL>;
735 def : PatGprGpr<riscv_clmulh, CLMULH>;
736 } // Predicates = [HasStdExtZbcOrZbkc]
738 let Predicates = [HasStdExtZbc] in
739 def : PatGprGpr<riscv_clmulr, CLMULR>;
741 let Predicates = [HasStdExtZbkx] in {
742 def : PatGprGpr<int_riscv_xperm4, XPERM4>;
743 def : PatGprGpr<int_riscv_xperm8, XPERM8>;
744 } // Predicates = [HasStdExtZbkx]