[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInstrInfoB.td
bloba2cd11b1f26ef262a4c615bf7a9f54a8a268fd78
1 //===-- RISCVInstrInfoB.td - RISC-V 'B' 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 'B' Bitmanip
10 // extension, version 0.93.
11 // This version is still experimental as the 'B' extension hasn't been
12 // ratified yet.
14 //===----------------------------------------------------------------------===//
16 //===----------------------------------------------------------------------===//
17 // Operand and SDNode transformation definitions.
18 //===----------------------------------------------------------------------===//
20 def riscv_clzw   : SDNode<"RISCVISD::CLZW",   SDT_RISCVIntUnaryOpW>;
21 def riscv_ctzw   : SDNode<"RISCVISD::CTZW",   SDT_RISCVIntUnaryOpW>;
22 def riscv_rolw   : SDNode<"RISCVISD::ROLW",   SDT_RISCVIntBinOpW>;
23 def riscv_rorw   : SDNode<"RISCVISD::RORW",   SDT_RISCVIntBinOpW>;
24 def riscv_fslw   : SDNode<"RISCVISD::FSLW",   SDT_RISCVIntShiftDOpW>;
25 def riscv_fsrw   : SDNode<"RISCVISD::FSRW",   SDT_RISCVIntShiftDOpW>;
26 def riscv_fsl    : SDNode<"RISCVISD::FSL",    SDTIntShiftDOp>;
27 def riscv_fsr    : SDNode<"RISCVISD::FSR",    SDTIntShiftDOp>;
28 def riscv_grev   : SDNode<"RISCVISD::GREV",   SDTIntBinOp>;
29 def riscv_grevw  : SDNode<"RISCVISD::GREVW",  SDT_RISCVIntBinOpW>;
30 def riscv_gorc   : SDNode<"RISCVISD::GORC",   SDTIntBinOp>;
31 def riscv_gorcw  : SDNode<"RISCVISD::GORCW",  SDT_RISCVIntBinOpW>;
32 def riscv_shfl   : SDNode<"RISCVISD::SHFL",   SDTIntBinOp>;
33 def riscv_shflw  : SDNode<"RISCVISD::SHFLW",  SDT_RISCVIntBinOpW>;
34 def riscv_unshfl : SDNode<"RISCVISD::UNSHFL", SDTIntBinOp>;
35 def riscv_unshflw: SDNode<"RISCVISD::UNSHFLW",SDT_RISCVIntBinOpW>;
36 def riscv_bcompress    : SDNode<"RISCVISD::BCOMPRESS",   SDTIntBinOp>;
37 def riscv_bcompressw   : SDNode<"RISCVISD::BCOMPRESSW",  SDT_RISCVIntBinOpW>;
38 def riscv_bdecompress  : SDNode<"RISCVISD::BDECOMPRESS", SDTIntBinOp>;
39 def riscv_bdecompressw : SDNode<"RISCVISD::BDECOMPRESSW",SDT_RISCVIntBinOpW>;
41 def UImmLog2XLenHalfAsmOperand : AsmOperandClass {
42   let Name = "UImmLog2XLenHalf";
43   let RenderMethod = "addImmOperands";
44   let DiagnosticType = "InvalidUImmLog2XLenHalf";
47 def shfl_uimm : Operand<XLenVT>, ImmLeaf<XLenVT, [{
48   if (Subtarget->is64Bit())
49     return isUInt<5>(Imm);
50   return isUInt<4>(Imm);
51 }]> {
52   let ParserMatchClass = UImmLog2XLenHalfAsmOperand;
53   let DecoderMethod = "decodeUImmOperand<5>";
54   let MCOperandPredicate = [{
55     int64_t Imm;
56     if (!MCOp.evaluateAsConstantImm(Imm))
57       return false;
58     if (STI.getTargetTriple().isArch64Bit())
59       return  isUInt<5>(Imm);
60     return isUInt<4>(Imm);
61   }];
64 def BCLRXForm : SDNodeXForm<imm, [{
65   // Find the lowest 0.
66   return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(),
67                                    SDLoc(N), N->getValueType(0));
68 }]>;
70 def BSETINVXForm : SDNodeXForm<imm, [{
71   // Find the lowest 1.
72   return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(),
73                                    SDLoc(N), N->getValueType(0));
74 }]>;
76 // Checks if this mask has a single 0 bit and cannot be used with ANDI.
77 def BCLRMask : ImmLeaf<XLenVT, [{
78   if (Subtarget->is64Bit())
79     return !isInt<12>(Imm) && isPowerOf2_64(~Imm);
80   return !isInt<12>(Imm) && isPowerOf2_32(~Imm);
81 }], BCLRXForm>;
83 // Checks if this mask has a single 1 bit and cannot be used with ORI/XORI.
84 def BSETINVMask : ImmLeaf<XLenVT, [{
85   if (Subtarget->is64Bit())
86     return !isInt<12>(Imm) && isPowerOf2_64(Imm);
87   return !isInt<12>(Imm) && isPowerOf2_32(Imm);
88 }], BSETINVXForm>;
90 // Check if (or r, i) can be optimized to (BSETI (BSETI r, i0), i1),
91 // in which i = (1 << i0) | (1 << i1).
92 def BSETINVTwoBitsMask : PatLeaf<(imm), [{
93   if (!N->hasOneUse())
94     return false;
95   // The immediate should not be a simm12.
96   if (isInt<12>(N->getSExtValue()))
97     return false;
98   // The immediate must have exactly two bits set.
99   return countPopulation(N->getZExtValue()) == 2;
100 }]>;
102 def TrailingZerosXForm : SDNodeXForm<imm, [{
103   uint64_t I = N->getZExtValue();
104   return CurDAG->getTargetConstant(countTrailingZeros(I), SDLoc(N),
105                                    N->getValueType(0));
106 }]>;
108 def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{
109   uint64_t I = N->getZExtValue();
110   return CurDAG->getTargetConstant(63 - countLeadingZeros(I), SDLoc(N),
111                                    N->getValueType(0));
112 }]>;
114 // Check if (or r, imm) can be optimized to (BSETI (ORI r, i0), i1),
115 // in which imm = i0 | (1 << i1).
116 def BSETINVORIMask : PatLeaf<(imm), [{
117   if (!N->hasOneUse())
118     return false;
119   // The immediate should not be a simm12.
120   if (isInt<12>(N->getSExtValue()))
121     return false;
122   // There should be only one set bit from bit 11 to the top.
123   return isPowerOf2_64(N->getZExtValue() & ~0x7ff);
124 }]>;
126 def BSETINVORIMaskLow : SDNodeXForm<imm, [{
127   return CurDAG->getTargetConstant(N->getZExtValue() & 0x7ff,
128                                    SDLoc(N), N->getValueType(0));
129 }]>;
131 // Check if (and r, i) can be optimized to (BCLRI (BCLRI r, i0), i1),
132 // in which i = ~((1<<i0) | (1<<i1)).
133 def BCLRITwoBitsMask : PatLeaf<(imm), [{
134   if (!N->hasOneUse())
135     return false;
136   // The immediate should not be a simm12.
137   if (isInt<12>(N->getSExtValue()))
138     return false;
139   // The immediate must have exactly two bits clear.
140   return countPopulation(N->getZExtValue()) == Subtarget->getXLen() - 2;
141 }]>;
143 def BCLRITwoBitsMaskLow : SDNodeXForm<imm, [{
144   return CurDAG->getTargetConstant(countTrailingZeros(~N->getZExtValue()),
145                                    SDLoc(N), N->getValueType(0));
146 }]>;
148 def BCLRITwoBitsMaskHigh : SDNodeXForm<imm, [{
149   uint64_t I = N->getSExtValue();
150   if (!Subtarget->is64Bit())
151     I |= 0xffffffffull << 32;
152   return CurDAG->getTargetConstant(63 - countLeadingZeros(~I), SDLoc(N),
153                                    N->getValueType(0));
154 }]>;
156 // Check if (and r, i) can be optimized to (BCLRI (ANDI r, i0), i1),
157 // in which i = i0 & ~(1<<i1).
158 def BCLRIANDIMask : PatLeaf<(imm), [{
159   if (!N->hasOneUse())
160     return false;
161   // The immediate should not be a simm12.
162   if (isInt<12>(N->getSExtValue()))
163     return false;
164   // There should be only one clear bit from bit 11 to the top.
165   uint64_t I = N->getZExtValue() | 0x7ff;
166   return Subtarget->is64Bit() ? isPowerOf2_64(~I) : isPowerOf2_32(~I);
167 }]>;
169 def BCLRIANDIMaskLow : SDNodeXForm<imm, [{
170   return CurDAG->getTargetConstant((N->getZExtValue() & 0x7ff) | ~0x7ffull,
171                                    SDLoc(N), N->getValueType(0));
172 }]>;
174 def C3LeftShift : PatLeaf<(imm), [{
175   uint64_t C = N->getZExtValue();
176   return C > 3 && ((C % 3) == 0) && isPowerOf2_64(C / 3);
177 }]>;
179 def C5LeftShift : PatLeaf<(imm), [{
180   uint64_t C = N->getZExtValue();
181   return C > 5 && ((C % 5) == 0) && isPowerOf2_64(C / 5);
182 }]>;
184 def C9LeftShift : PatLeaf<(imm), [{
185   uint64_t C = N->getZExtValue();
186   return C > 9 && ((C % 9) == 0) && isPowerOf2_64(C / 9);
187 }]>;
189 def CSImm12MulBy4 : PatLeaf<(imm), [{
190   if (!N->hasOneUse())
191     return false;
192   int64_t C = N->getSExtValue();
193   // Skip if C is simm12 or can be optimized by the PatLeaf AddiPair.
194   return !isInt<13>(C) && isInt<14>(C) && (C & 3) == 0;
195 }]>;
197 def CSImm12MulBy8 : PatLeaf<(imm), [{
198   if (!N->hasOneUse())
199     return false;
200   int64_t C = N->getSExtValue();
201   // Skip if C is simm12 or can be optimized by the PatLeaf AddiPair.
202   return !isInt<13>(C) && isInt<15>(C) && (C & 7) == 0;
203 }]>;
205 def SimmShiftRightBy2XForm : SDNodeXForm<imm, [{
206   return CurDAG->getTargetConstant(N->getSExtValue() >> 2, SDLoc(N),
207                                    N->getValueType(0));
208 }]>;
210 def SimmShiftRightBy3XForm : SDNodeXForm<imm, [{
211   return CurDAG->getTargetConstant(N->getSExtValue() >> 3, SDLoc(N),
212                                    N->getValueType(0));
213 }]>;
215 //===----------------------------------------------------------------------===//
216 // Instruction class templates
217 //===----------------------------------------------------------------------===//
219 // Some of these templates should be moved to RISCVInstrFormats.td once the B
220 // extension has been ratified.
222 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
223 class RVBUnary<bits<7> funct7, bits<5> funct5, bits<3> funct3,
224                RISCVOpcode opcode, string opcodestr>
225     : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
226               opcodestr, "$rd, $rs1"> {
227   let rs2 = funct5;
230 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
231 class RVBShift_ri<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
232                   string opcodestr>
233     : RVInstIShift<imm11_7, funct3, opcode, (outs GPR:$rd),
234                    (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
235                    "$rd, $rs1, $shamt">;
237 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
238 class RVBShiftW_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
239                    string opcodestr>
240     : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
241                     (ins GPR:$rs1, uimm5:$shamt), opcodestr,
242                     "$rd, $rs1, $shamt">;
244 // Using RVInstIShiftW since it allocates 5 bits instead of 6 to shamt.
245 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
246 class RVBShfl_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
247                  string opcodestr>
248     : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
249                     (ins GPR:$rs1, shfl_uimm:$shamt), opcodestr,
250                     "$rd, $rs1, $shamt">;
252 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
253 class RVBTernaryR<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
254                   string opcodestr, string argstr>
255     : RVInstR4<funct2, funct3, opcode, (outs GPR:$rd),
256                (ins GPR:$rs1, GPR:$rs2, GPR:$rs3), opcodestr, argstr>;
258 // Currently used by FSRI only
259 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
260 class RVBTernaryImm6<bits<3> funct3, RISCVOpcode opcode,
261                      string opcodestr, string argstr>
262     : RVInst<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt),
263              opcodestr, argstr, [], InstFormatR4> {
264   bits<5> rs3;
265   bits<6> shamt;
266   bits<5> rs1;
267   bits<5> rd;
269   let Inst{31-27} = rs3;
270   let Inst{26} = 1;
271   let Inst{25-20} = shamt;
272   let Inst{19-15} = rs1;
273   let Inst{14-12} = funct3;
274   let Inst{11-7} = rd;
275   let Opcode = opcode.Value;
278 // Currently used by FSRIW only
279 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
280 class RVBTernaryImm5<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
281                      string opcodestr, string argstr>
282     : RVInst<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs3, uimm5:$shamt),
283              opcodestr, argstr, [], InstFormatR4> {
284   bits<5> rs3;
285   bits<5> shamt;
286   bits<5> rs1;
287   bits<5> rd;
289   let Inst{31-27} = rs3;
290   let Inst{26-25} = funct2;
291   let Inst{24-20} = shamt;
292   let Inst{19-15} = rs1;
293   let Inst{14-12} = funct3;
294   let Inst{11-7} = rd;
295   let Opcode = opcode.Value;
298 //===----------------------------------------------------------------------===//
299 // Instructions
300 //===----------------------------------------------------------------------===//
302 let Predicates = [HasStdExtZbbOrZbp] in {
303 def ANDN  : ALU_rr<0b0100000, 0b111, "andn">,
304             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
305 def ORN   : ALU_rr<0b0100000, 0b110, "orn">,
306             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
307 def XNOR  : ALU_rr<0b0100000, 0b100, "xnor">,
308             Sched<[WriteIALU, ReadIALU, ReadIALU]>;
309 } // Predicates = [HasStdExtZbbOrZbp]
311 let Predicates = [HasStdExtZba] in {
312 def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,
313              Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
314 def SH2ADD : ALU_rr<0b0010000, 0b100, "sh2add">,
315              Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
316 def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,
317              Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
318 } // Predicates = [HasStdExtZba]
320 let Predicates = [HasStdExtZbbOrZbp] in {
321 def ROL   : ALU_rr<0b0110000, 0b001, "rol">,
322             Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
323 def ROR   : ALU_rr<0b0110000, 0b101, "ror">,
324             Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
325 } // Predicates = [HasStdExtZbbOrZbp]
327 let Predicates = [HasStdExtZbs] in {
328 def BCLR : ALU_rr<0b0100100, 0b001, "bclr">, Sched<[]>;
329 def BSET : ALU_rr<0b0010100, 0b001, "bset">, Sched<[]>;
330 def BINV : ALU_rr<0b0110100, 0b001, "binv">, Sched<[]>;
331 def BEXT : ALU_rr<0b0100100, 0b101, "bext">, Sched<[]>;
332 } // Predicates = [HasStdExtZbs]
334 let Predicates = [HasStdExtZbp] in {
335 def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>;
336 def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>;
337 } // Predicates = [HasStdExtZbp]
339 let Predicates = [HasStdExtZbp] in {
340 def XPERMN : ALU_rr<0b0010100, 0b010, "xperm.n">, Sched<[]>;
341 def XPERMB : ALU_rr<0b0010100, 0b100, "xperm.b">, Sched<[]>;
342 def XPERMH : ALU_rr<0b0010100, 0b110, "xperm.h">, Sched<[]>;
343 } // Predicates = [HasStdExtZbp]
345 let Predicates = [HasStdExtZbbOrZbp] in
346 def RORI  : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">,
347             Sched<[WriteRotateImm, ReadRotateImm]>;
349 let Predicates = [HasStdExtZbs] in {
350 def BCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "bclri">, Sched<[]>;
351 def BSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "bseti">, Sched<[]>;
352 def BINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "binvi">, Sched<[]>;
353 def BEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "bexti">, Sched<[]>;
354 } // Predicates = [HasStdExtZbs]
356 let Predicates = [HasStdExtZbp] in {
357 def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">, Sched<[]>;
358 def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">, Sched<[]>;
359 } // Predicates = [HasStdExtZbp]
361 let Predicates = [HasStdExtZbt] in {
362 def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
363            Sched<[]>;
364 def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
365            Sched<[]>;
366 def FSL  : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
367            Sched<[]>;
368 def FSR  : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
369            Sched<[]>;
370 def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
371                           "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
372 } // Predicates = [HasStdExtZbt]
374 let Predicates = [HasStdExtZbb] in {
375 def CLZ  : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0010011>, "clz">,
376            Sched<[WriteCLZ, ReadCLZ]>;
377 def CTZ  : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0010011>, "ctz">,
378            Sched<[WriteCTZ, ReadCTZ]>;
379 def CPOP : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0010011>, "cpop">,
380            Sched<[WriteCPOP, ReadCPOP]>;
381 } // Predicates = [HasStdExtZbb]
383 let Predicates = [HasStdExtZbm, IsRV64] in
384 def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, RISCVOpcode<0b0010011>,
385                         "bmatflip">, Sched<[]>;
387 let Predicates = [HasStdExtZbb] in {
388 def SEXTB : RVBUnary<0b0110000, 0b00100, 0b001, RISCVOpcode<0b0010011>,
389                      "sext.b">, Sched<[WriteIALU, ReadIALU]>;
390 def SEXTH : RVBUnary<0b0110000, 0b00101, 0b001, RISCVOpcode<0b0010011>,
391                      "sext.h">, Sched<[WriteIALU, ReadIALU]>;
392 } // Predicates = [HasStdExtZbb]
394 let Predicates = [HasStdExtZbr] in {
395 def CRC32B : RVBUnary<0b0110000, 0b10000, 0b001, RISCVOpcode<0b0010011>,
396                       "crc32.b">, Sched<[]>;
397 def CRC32H : RVBUnary<0b0110000, 0b10001, 0b001, RISCVOpcode<0b0010011>,
398                       "crc32.h">, Sched<[]>;
399 def CRC32W : RVBUnary<0b0110000, 0b10010, 0b001, RISCVOpcode<0b0010011>,
400                       "crc32.w">, Sched<[]>;
401 } // Predicates = [HasStdExtZbr]
403 let Predicates = [HasStdExtZbr, IsRV64] in
404 def CRC32D  : RVBUnary<0b0110000, 0b10011, 0b001, RISCVOpcode<0b0010011>,
405                        "crc32.d">, Sched<[]>;
407 let Predicates = [HasStdExtZbr] in {
408 def CRC32CB : RVBUnary<0b0110000, 0b11000, 0b001, RISCVOpcode<0b0010011>,
409                        "crc32c.b">, Sched<[]>;
410 def CRC32CH : RVBUnary<0b0110000, 0b11001, 0b001, RISCVOpcode<0b0010011>,
411                        "crc32c.h">, Sched<[]>;
412 def CRC32CW : RVBUnary<0b0110000, 0b11010, 0b001, RISCVOpcode<0b0010011>,
413                        "crc32c.w">, Sched<[]>;
414 } // Predicates = [HasStdExtZbr]
416 let Predicates = [HasStdExtZbr, IsRV64] in
417 def CRC32CD : RVBUnary<0b0110000, 0b11011, 0b001, RISCVOpcode<0b0010011>,
418                        "crc32c.d">, Sched<[]>;
420 let Predicates = [HasStdExtZbc] in {
421 def CLMUL  : ALU_rr<0b0000101, 0b001, "clmul">, Sched<[]>;
422 def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">, Sched<[]>;
423 def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh">, Sched<[]>;
424 } // Predicates = [HasStdExtZbc]
426 let Predicates = [HasStdExtZbb] in {
427 def MIN  : ALU_rr<0b0000101, 0b100, "min">,
428            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
429 def MINU : ALU_rr<0b0000101, 0b101, "minu">,
430            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
431 def MAX  : ALU_rr<0b0000101, 0b110, "max">,
432            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
433 def MAXU : ALU_rr<0b0000101, 0b111, "maxu">,
434            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
435 } // Predicates = [HasStdExtZbb]
437 let Predicates = [HasStdExtZbp] in {
438 def SHFL   : ALU_rr<0b0000100, 0b001, "shfl">, Sched<[]>;
439 def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">, Sched<[]>;
440 } // Predicates = [HasStdExtZbp]
442 let Predicates = [HasStdExtZbe] in {
443 // NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
444 // bext in the 0.93 spec.
445 def BDECOMPRESS : ALU_rr<0b0100100, 0b110, "bdecompress">, Sched<[]>;
446 def BCOMPRESS   : ALU_rr<0b0000100, 0b110, "bcompress">, Sched<[]>;
447 } // Predicates = [HasStdExtZbe]
449 let Predicates = [HasStdExtZbp] in {
450 def PACK  : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>;
451 def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>;
452 def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
453 } // Predicates = [HasStdExtZbp]
455 let Predicates = [HasStdExtZbm, IsRV64] in {
456 def BMATOR   : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>;
457 def BMATXOR  : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>;
458 } // Predicates = [HasStdExtZbm, IsRV64]
460 let Predicates = [HasStdExtZbf] in
461 def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>;
463 let Predicates = [HasStdExtZbp] in {
464 def SHFLI   : RVBShfl_ri<0b0000100, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>;
465 def UNSHFLI : RVBShfl_ri<0b0000100, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>;
466 } // Predicates = [HasStdExtZbp]
468 let Predicates = [HasStdExtZba, IsRV64] in {
469 def SLLIUW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,
470              Sched<[WriteShiftImm32, ReadShiftImm32]>;
471 def ADDUW : ALUW_rr<0b0000100, 0b000, "add.uw">,
472             Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
473 def SH1ADDUW : ALUW_rr<0b0010000, 0b010, "sh1add.uw">,
474                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
475 def SH2ADDUW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,
476                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
477 def SH3ADDUW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,
478                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
479 } // Predicates = [HasStdExtZbb, IsRV64]
481 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
482 def ROLW  : ALUW_rr<0b0110000, 0b001, "rolw">,
483             Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
484 def RORW  : ALUW_rr<0b0110000, 0b101, "rorw">,
485             Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
486 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
488 let Predicates = [HasStdExtZbs, IsRV64] in {
489 // NOTE: These instructions have been removed from the 0.94 spec. As a result
490 // we have no isel patterns for them.
491 def BCLRW : ALUW_rr<0b0100100, 0b001, "bclrw">, Sched<[]>;
492 def BSETW : ALUW_rr<0b0010100, 0b001, "bsetw">, Sched<[]>;
493 def BINVW : ALUW_rr<0b0110100, 0b001, "binvw">, Sched<[]>;
494 def BEXTW : ALUW_rr<0b0100100, 0b101, "bextw">, Sched<[]>;
495 } // Predicates = [HasStdExtZbs, IsRV64]
497 let Predicates = [HasStdExtZbp, IsRV64] in {
498 def GORCW  : ALUW_rr<0b0010100, 0b101, "gorcw">, Sched<[]>;
499 def GREVW  : ALUW_rr<0b0110100, 0b101, "grevw">, Sched<[]>;
500 } // Predicates = [HasStdExtZbp, IsRV64]
502 let Predicates = [HasStdExtZbp, IsRV64] in {
503 def XPERMW : ALU_rr<0b0010100, 0b000, "xperm.w">, Sched<[]>;
504 } // Predicates = [HasStdExtZbp, IsRV64]
506 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
507 def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">,
508             Sched<[WriteRotateImm32, ReadRotateImm32]>;
510 let Predicates = [HasStdExtZbs, IsRV64] in {
511 // NOTE: These instructions have been removed from the 0.94 spec. As a result
512 // we have no isel patterns for them.
513 def BCLRIW : RVBShiftW_ri<0b0100100, 0b001, OPC_OP_IMM_32, "bclriw">,
514               Sched<[]>;
515 def BSETIW : RVBShiftW_ri<0b0010100, 0b001, OPC_OP_IMM_32, "bsetiw">,
516               Sched<[]>;
517 def BINVIW : RVBShiftW_ri<0b0110100, 0b001, OPC_OP_IMM_32, "binviw">,
518               Sched<[]>;
519 } // Predicates = [HasStdExtZbs, IsRV64]
521 let Predicates = [HasStdExtZbp, IsRV64] in {
522 def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">, Sched<[]>;
523 def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">, Sched<[]>;
524 } // Predicates = [HasStdExtZbp, IsRV64]
526 let Predicates = [HasStdExtZbt, IsRV64] in {
527 def FSLW  : RVBTernaryR<0b10, 0b001, OPC_OP_32,
528                         "fslw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
529 def FSRW  : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
530                         "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
531 def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
532                            "fsriw", "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
533 } // Predicates = [HasStdExtZbt, IsRV64]
535 let Predicates = [HasStdExtZbb, IsRV64] in {
536 def CLZW   : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0011011>,
537                       "clzw">, Sched<[WriteCLZ32, ReadCLZ32]>;
538 def CTZW   : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0011011>,
539                       "ctzw">, Sched<[WriteCTZ32, ReadCTZ32]>;
540 def CPOPW  : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0011011>,
541                       "cpopw">, Sched<[WriteCPOP32, ReadCPOP32]>;
542 } // Predicates = [HasStdExtZbb, IsRV64]
544 let Predicates = [HasStdExtZbp, IsRV64] in {
545 def SHFLW   : ALUW_rr<0b0000100, 0b001, "shflw">, Sched<[]>;
546 def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">, Sched<[]>;
547 } // Predicates = [HasStdExtZbp, IsRV64]
549 let Predicates = [HasStdExtZbe, IsRV64] in {
550 // NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
551 // bextw in the 0.93 spec.
552 def BDECOMPRESSW : ALUW_rr<0b0100100, 0b110, "bdecompressw">, Sched<[]>;
553 def BCOMPRESSW   : ALUW_rr<0b0000100, 0b110, "bcompressw">, Sched<[]>;
554 } // Predicates = [HasStdExtZbe, IsRV64]
556 let Predicates = [HasStdExtZbp, IsRV64] in {
557 def PACKW  : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>;
558 def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
559 } // Predicates = [HasStdExtZbp, IsRV64]
561 let Predicates = [HasStdExtZbf, IsRV64] in
562 def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>;
564 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
565 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
566 def ZEXTH_RV32 : RVInstR<0b0000100, 0b100, OPC_OP, (outs GPR:$rd),
567                          (ins GPR:$rs1), "zext.h", "$rd, $rs1">,
568                  Sched<[WriteIALU, ReadIALU]> {
569   let rs2 = 0b00000;
571 } // Predicates = [HasStdExtZbbOrZbp, IsRV32]
573 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
574 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
575 def ZEXTH_RV64 : RVInstR<0b0000100, 0b100, OPC_OP_32, (outs GPR:$rd),
576                          (ins GPR:$rs1), "zext.h", "$rd, $rs1">,
577                  Sched<[WriteIALU, ReadIALU]> {
578   let rs2 = 0b00000;
580 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
582 // We treat rev8 and orc.b as standalone instructions even though they use a
583 // portion of the encodings for grevi and gorci. This allows us to support only
584 // those encodings when only Zbb is enabled. We do this even when grevi and
585 // gorci are available with Zbp. Trying to use 'HasStdExtZbb, NotHasStdExtZbp'
586 // causes diagnostics to suggest that Zbp rather than Zbb is required for rev8
587 // or gorci. Since Zbb is closer to being finalized than Zbp this will be
588 // misleading to users.
589 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
590 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
591 def REV8_RV32 : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
592                         "rev8", "$rd, $rs1">, Sched<[WriteREV8, ReadREV8]> {
593   let imm12 = { 0b01101, 0b0011000 };
595 } // Predicates = [HasStdExtZbbOrZbp, IsRV32]
597 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
598 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
599 def REV8_RV64 : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
600                         "rev8", "$rd, $rs1">, Sched<[WriteREV8, ReadREV8]> {
601   let imm12 = { 0b01101, 0b0111000 };
603 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
605 let Predicates = [HasStdExtZbbOrZbp] in {
606 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
607 def ORCB : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
608                    "orc.b", "$rd, $rs1">, Sched<[WriteORCB, ReadORCB]> {
609   let imm12 = { 0b00101, 0b0000111 };
611 } // Predicates = [HasStdExtZbbOrZbp]
613 //===----------------------------------------------------------------------===//
614 // Future compressed instructions
615 //===----------------------------------------------------------------------===//
617 // The presence of these instructions in the B extension is purely experimental
618 // and they should be moved to the C extension as soon as they are ratified.
620 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
621 class RVBInstC<bits<2> funct2, string opcodestr>
622     : RVInst16<(outs GPRC:$rs_wb), (ins GPRC:$rs), opcodestr, "$rs", [],
623                InstFormatCR> {
624   bits<3> rs;
625   let Constraints = "$rs = $rs_wb";
627   let Inst{15-12} = 0b0110;
628   let Inst{11-10} = funct2;
629   let Inst{9-7} = rs;
630   let Inst{6-0} = 0b0000001;
633 // The namespace RVBC exists to avoid encoding conflicts with the compressed
634 // instructions c.addi16sp and c.lui already implemented in the C extension.
636 let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC] in {
637 def C_NOT : RVBInstC<0b00, "c.not">, Sched<[]>;
638 def C_NEG : RVBInstC<0b01, "c.neg">, Sched<[]>;
639 } // DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC]
641 let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtZba, HasStdExtC, IsRV64] in
642 def C_ZEXTW : RVBInstC<0b10, "c.zext.w">, Sched<[]>;
644 //===----------------------------------------------------------------------===//
645 // Pseudo Instructions
646 //===----------------------------------------------------------------------===//
648 let Predicates = [HasStdExtZba, IsRV64] in {
649 // NOTE: The 0.93 spec shows zext.w as an alias of pack/packw. It has been
650 // changed to add.uw in a draft after 0.94.
651 def : InstAlias<"zext.w $rd, $rs", (ADDUW GPR:$rd, GPR:$rs, X0)>;
654 let Predicates = [HasStdExtZbp] in {
655 def : InstAlias<"rev.p $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00001)>;
656 def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>;
657 def : InstAlias<"rev.n $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00011)>;
658 def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>;
659 def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>;
660 def : InstAlias<"rev.b $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00111)>;
661 def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>;
662 def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>;
663 def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>;
664 def : InstAlias<"rev.h $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b01111)>;
666 def : InstAlias<"zip.n $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0001)>;
667 def : InstAlias<"unzip.n $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>;
668 def : InstAlias<"zip2.b $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0010)>;
669 def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>;
670 def : InstAlias<"zip.b $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0011)>;
671 def : InstAlias<"unzip.b $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>;
672 def : InstAlias<"zip4.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0100)>;
673 def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>;
674 def : InstAlias<"zip2.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0110)>;
675 def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>;
676 def : InstAlias<"zip.h $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0111)>;
677 def : InstAlias<"unzip.h $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>;
679 def : InstAlias<"orc.p $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00001)>;
680 def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>;
681 def : InstAlias<"orc.n $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00011)>;
682 def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>;
683 def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>;
684 // orc.b is considered an instruction rather than an alias.
685 def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>;
686 def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>;
687 def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>;
688 def : InstAlias<"orc.h $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b01111)>;
689 } // Predicates = [HasStdExtZbp]
691 let Predicates = [HasStdExtZbp, IsRV32] in {
692 def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>;
693 // rev8 is considered an instruction rather than an alias.
694 def : InstAlias<"rev4 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11100)>;
695 def : InstAlias<"rev2 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11110)>;
696 def : InstAlias<"rev $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b11111)>;
698 def : InstAlias<"zip8 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1000)>;
699 def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>;
700 def : InstAlias<"zip4 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1100)>;
701 def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>;
702 def : InstAlias<"zip2 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1110)>;
703 def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>;
704 def : InstAlias<"zip $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b1111)>;
705 def : InstAlias<"unzip $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b1111)>;
707 def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>;
708 def : InstAlias<"orc8 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11000)>;
709 def : InstAlias<"orc4 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11100)>;
710 def : InstAlias<"orc2 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11110)>;
711 def : InstAlias<"orc $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b11111)>;
712 } // Predicates = [HasStdExtZbp, IsRV32]
714 let Predicates = [HasStdExtZbp, IsRV64] in {
715 def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>;
716 def : InstAlias<"rev8.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011000)>;
717 def : InstAlias<"rev4.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011100)>;
718 def : InstAlias<"rev2.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011110)>;
719 def : InstAlias<"rev.w $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b011111)>;
720 def : InstAlias<"rev32 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b100000)>;
721 def : InstAlias<"rev16 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b110000)>;
722 // rev8 is considered an instruction rather than an alias.
723 def : InstAlias<"rev4 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111100)>;
724 def : InstAlias<"rev2 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111110)>;
725 def : InstAlias<"rev $rd, $rs",     (GREVI GPR:$rd, GPR:$rs, 0b111111)>;
727 def : InstAlias<"zip8.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01000)>;
728 def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>;
729 def : InstAlias<"zip4.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01100)>;
730 def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>;
731 def : InstAlias<"zip2.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01110)>;
732 def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>;
733 def : InstAlias<"zip.w $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b01111)>;
734 def : InstAlias<"unzip.w $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>;
735 def : InstAlias<"zip16 $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b10000)>;
736 def : InstAlias<"unzip16 $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>;
737 def : InstAlias<"zip8 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11000)>;
738 def : InstAlias<"unzip8 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>;
739 def : InstAlias<"zip4 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11100)>;
740 def : InstAlias<"unzip4 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>;
741 def : InstAlias<"zip2 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11110)>;
742 def : InstAlias<"unzip2 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>;
743 def : InstAlias<"zip $rd, $rs",      (SHFLI   GPR:$rd, GPR:$rs, 0b11111)>;
744 def : InstAlias<"unzip $rd, $rs",    (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>;
746 def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>;
747 def : InstAlias<"orc8.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011000)>;
748 def : InstAlias<"orc4.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011100)>;
749 def : InstAlias<"orc2.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011110)>;
750 def : InstAlias<"orc.w $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b011111)>;
751 def : InstAlias<"orc32 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b100000)>;
752 def : InstAlias<"orc16 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b110000)>;
753 def : InstAlias<"orc8 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111000)>;
754 def : InstAlias<"orc4 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111100)>;
755 def : InstAlias<"orc2 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111110)>;
756 def : InstAlias<"orc $rd, $rs",     (GORCI GPR:$rd, GPR:$rs, 0b111111)>;
757 } // Predicates = [HasStdExtZbp, IsRV64]
759 let Predicates = [HasStdExtZbbOrZbp] in {
760 def : InstAlias<"ror $rd, $rs1, $shamt",
761                 (RORI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
762 } // Predicates = [HasStdExtZbbOrZbp]
764 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
765 def : InstAlias<"rorw $rd, $rs1, $shamt",
766                 (RORIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
767 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
769 let Predicates = [HasStdExtZbp] in {
770 def : InstAlias<"grev $rd, $rs1, $shamt",
771                 (GREVI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
772 def : InstAlias<"gorc $rd, $rs1, $shamt",
773                 (GORCI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
774 def : InstAlias<"shfl $rd, $rs1, $shamt",
775                 (SHFLI  GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
776 def : InstAlias<"unshfl $rd, $rs1, $shamt",
777                 (UNSHFLI  GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
778 } // Predicates = [HasStdExtZbp]
780 let Predicates = [HasStdExtZbp, IsRV64] in {
781 def : InstAlias<"grevw $rd, $rs1, $shamt",
782                 (GREVIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
783 def : InstAlias<"gorcw $rd, $rs1, $shamt",
784                 (GORCIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
785 } // Predicates = [HasStdExtZbp, IsRV64]
787 let Predicates = [HasStdExtZbs] in {
788 def : InstAlias<"bset $rd, $rs1, $shamt",
789                 (BSETI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
790 def : InstAlias<"bclr $rd, $rs1, $shamt",
791                 (BCLRI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
792 def : InstAlias<"binv $rd, $rs1, $shamt",
793                 (BINVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
794 def : InstAlias<"bext $rd, $rs1, $shamt",
795                 (BEXTI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
796 } // Predicates = [HasStdExtZbs]
798 //===----------------------------------------------------------------------===//
799 // Compressed Instruction patterns
800 //===----------------------------------------------------------------------===//
801 let Predicates = [HasStdExtZbproposedc, HasStdExtC] in {
802 def : CompressPat<(XORI GPRC:$rs1, GPRC:$rs1, -1),
803                   (C_NOT GPRC:$rs1)>;
804 def : CompressPat<(SUB GPRC:$rs1, X0, GPRC:$rs1),
805                   (C_NEG GPRC:$rs1)>;
806 } // Predicates = [HasStdExtZbproposedc, HasStdExtC]
808 let Predicates = [HasStdExtZbproposedc, HasStdExtZba, HasStdExtC, IsRV64] in {
809 def : CompressPat<(ADDUW GPRC:$rs1, GPRC:$rs1, X0),
810                   (C_ZEXTW GPRC:$rs1)>;
811 } // Predicates = [HasStdExtZbproposedc, HasStdExtC, IsRV64]
813 //===----------------------------------------------------------------------===//
814 // Codegen patterns
815 //===----------------------------------------------------------------------===//
817 let Predicates = [HasStdExtZbbOrZbp] in {
818 def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
819 def : Pat<(or  GPR:$rs1, (not GPR:$rs2)), (ORN  GPR:$rs1, GPR:$rs2)>;
820 def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
821 } // Predicates = [HasStdExtZbbOrZbp]
823 let Predicates = [HasStdExtZbbOrZbp] in {
824 def : PatGprGpr<rotl, ROL>;
825 def : PatGprGpr<rotr, ROR>;
826 } // Predicates = [HasStdExtZbbOrZbp]
828 let Predicates = [HasStdExtZbs] in {
829 def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
830           (BCLR GPR:$rs1, GPR:$rs2)>;
831 def : Pat<(and (rotl -2, GPR:$rs2), GPR:$rs1), (BCLR GPR:$rs1, GPR:$rs2)>;
832 def : Pat<(or (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
833           (BSET GPR:$rs1, GPR:$rs2)>;
834 def : Pat<(xor (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
835           (BINV GPR:$rs1, GPR:$rs2)>;
836 def : Pat<(and (shiftop<srl> GPR:$rs1, GPR:$rs2), 1),
837           (BEXT GPR:$rs1, GPR:$rs2)>;
839 def : Pat<(shiftop<shl> 1, GPR:$rs2),
840           (BSET X0, GPR:$rs2)>;
842 def : Pat<(and GPR:$rs1, BCLRMask:$mask),
843           (BCLRI GPR:$rs1, BCLRMask:$mask)>;
844 def : Pat<(or GPR:$rs1, BSETINVMask:$mask),
845           (BSETI GPR:$rs1, BSETINVMask:$mask)>;
846 def : Pat<(xor GPR:$rs1, BSETINVMask:$mask),
847           (BINVI GPR:$rs1, BSETINVMask:$mask)>;
849 def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)),
850           (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
852 def : Pat<(or GPR:$r, BSETINVTwoBitsMask:$i),
853           (BSETI (BSETI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
854                  (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
855 def : Pat<(xor GPR:$r, BSETINVTwoBitsMask:$i),
856           (BINVI (BINVI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
857                  (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
858 def : Pat<(or GPR:$r, BSETINVORIMask:$i),
859           (BSETI (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
860                  (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
861 def : Pat<(xor GPR:$r, BSETINVORIMask:$i),
862           (BINVI (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
863                  (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
864 def : Pat<(and GPR:$r, BCLRITwoBitsMask:$i),
865           (BCLRI (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i)),
866                  (BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;
867 def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
868           (BCLRI (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i)),
869                  (BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
872 // There's no encoding for roli in the the 'B' extension as it can be
873 // implemented with rori by negating the immediate.
874 let Predicates = [HasStdExtZbbOrZbp] in {
875 def : PatGprImm<rotr, RORI, uimmlog2xlen>;
876 def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
877           (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
879 // We treat orc.b as a separate instruction, so match it directly. We also
880 // lower the Zbb orc.b intrinsic to this.
881 def : Pat<(riscv_gorc GPR:$rs1, 7), (ORCB GPR:$rs1)>;
884 let Predicates = [HasStdExtZbp] in {
885 def : PatGprGpr<riscv_grev, GREV>;
886 def : PatGprGpr<riscv_gorc, GORC>;
887 def : PatGprGpr<riscv_shfl, SHFL>;
888 def : PatGprGpr<riscv_unshfl, UNSHFL>;
889 def : PatGprGpr<int_riscv_xperm_n, XPERMN>;
890 def : PatGprGpr<int_riscv_xperm_b, XPERMB>;
891 def : PatGprGpr<int_riscv_xperm_h, XPERMH>;
892 def : PatGprGpr<int_riscv_xperm_w, XPERMW>;
893 def : PatGprImm<riscv_shfl, SHFLI, shfl_uimm>;
894 def : PatGprImm<riscv_unshfl, UNSHFLI, shfl_uimm>;
895 def : PatGprImm<riscv_grev, GREVI, uimmlog2xlen>;
896 def : PatGprImm<riscv_gorc, GORCI, uimmlog2xlen>;
897 } // Predicates = [HasStdExtZbp]
899 let Predicates = [HasStdExtZbp, IsRV32] in {
900 def : Pat<(i32 (rotr (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
901 def : Pat<(i32 (rotl (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
903 // We treat rev8 as a separate instruction, so match it directly.
904 def : Pat<(i32 (riscv_grev GPR:$rs1, 24)), (REV8_RV32 GPR:$rs1)>;
905 } // Predicates = [HasStdExtZbp, IsRV32]
907 let Predicates = [HasStdExtZbp, IsRV64] in {
908 // We treat rev8 as a separate instruction, so match it directly.
909 def : Pat<(i64 (riscv_grev GPR:$rs1, 56)), (REV8_RV64 GPR:$rs1)>;
910 } // Predicates = [HasStdExtZbp, IsRV64]
912 let Predicates = [HasStdExtZbt] in {
913 def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)),
914           (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
916 def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3),
917           (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
918 def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1),
919           (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
920 def : Pat<(select (XLenVT (setne GPR:$x, simm12_plus1:$y)), GPR:$rs1, GPR:$rs3),
921           (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
922 def : Pat<(select (XLenVT (seteq GPR:$x, simm12_plus1:$y)), GPR:$rs3, GPR:$rs1),
923           (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
924 def : Pat<(select (XLenVT (setne GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3),
925           (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
926 def : Pat<(select (XLenVT (seteq GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
927           (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
928 def : Pat<(select (XLenVT (setuge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
929           (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
930 def : Pat<(select (XLenVT (setule GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
931           (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
932 def : Pat<(select (XLenVT (setge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
933           (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
934 def : Pat<(select (XLenVT (setle GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
935           (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
936 def : Pat<(select GPR:$rs2, GPR:$rs1, GPR:$rs3),
937           (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
938 } // Predicates = [HasStdExtZbt]
940 // fshl and fshr concatenate their operands in the same order. fsr and fsl
941 // instruction use different orders. fshl will return its first operand for
942 // shift of zero, fshr will return its second operand. fsl and fsr both return
943 // $rs1 so the patterns need to have different operand orders.
944 let Predicates = [HasStdExtZbt] in {
945 def : Pat<(riscv_fsl GPR:$rs1, GPR:$rs3, GPR:$rs2),
946           (FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
947 def : Pat<(riscv_fsr GPR:$rs3, GPR:$rs1, GPR:$rs2),
948           (FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
950 def : Pat<(fshr GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
951           (FSRI GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt)>;
952 // We can use FSRI for fshl by immediate if we subtract the immediate from
953 // XLen and swap the operands.
954 def : Pat<(fshl GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
955           (FSRI GPR:$rs1, GPR:$rs3, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
956 } // Predicates = [HasStdExtZbt]
958 let Predicates = [HasStdExtZbb] in {
959 def : PatGpr<ctlz, CLZ>;
960 def : PatGpr<cttz, CTZ>;
961 def : PatGpr<ctpop, CPOP>;
962 } // Predicates = [HasStdExtZbb]
964 let Predicates = [HasStdExtZbb] in {
965 def : Pat<(sext_inreg GPR:$rs1, i8), (SEXTB GPR:$rs1)>;
966 def : Pat<(sext_inreg GPR:$rs1, i16), (SEXTH GPR:$rs1)>;
969 let Predicates = [HasStdExtZbb] in {
970 def : PatGprGpr<smin, MIN>;
971 def : PatGprGpr<smax, MAX>;
972 def : PatGprGpr<umin, MINU>;
973 def : PatGprGpr<umax, MAXU>;
974 } // Predicates = [HasStdExtZbb]
976 let Predicates = [HasStdExtZbb, IsRV32] in {
977 def : Pat<(i32 (bswap GPR:$rs1)), (REV8_RV32 GPR:$rs1)>;
978 } // Predicates = [HasStdExtZbb, IsRV32]
980 let Predicates = [HasStdExtZbb, IsRV64] in {
981 def : Pat<(i64 (bswap GPR:$rs1)), (REV8_RV64 GPR:$rs1)>;
982 } // Predicates = [HasStdExtZbb, IsRV64]
984 let Predicates = [HasStdExtZbp, IsRV32] in {
985 def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))),
986           (PACK GPR:$rs1, GPR:$rs2)>;
987 def : Pat<(i32 (or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16)))),
988           (PACKU GPR:$rs1, GPR:$rs2)>;
991 let Predicates = [HasStdExtZbp, IsRV64] in {
992 def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
993           (PACK GPR:$rs1, GPR:$rs2)>;
994 def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
995           (PACKU GPR:$rs1, GPR:$rs2)>;
997 let Predicates = [HasStdExtZbp] in
998 def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
999               (and GPR:$rs1, 0x00FF)),
1000           (PACKH GPR:$rs1, GPR:$rs2)>;
1002 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
1003 def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV32 GPR:$rs)>;
1004 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
1005 def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV64 GPR:$rs)>;
1007 // Pattern to exclude simm12 immediates from matching.
1008 def non_imm12 : PatLeaf<(XLenVT GPR:$a), [{
1009   auto *C = dyn_cast<ConstantSDNode>(N);
1010   return !C || !isInt<12>(C->getSExtValue());
1011 }]>;
1013 let Predicates = [HasStdExtZba] in {
1014 def : Pat<(add (shl GPR:$rs1, (XLenVT 1)), non_imm12:$rs2),
1015           (SH1ADD GPR:$rs1, GPR:$rs2)>;
1016 def : Pat<(add (shl GPR:$rs1, (XLenVT 2)), non_imm12:$rs2),
1017           (SH2ADD GPR:$rs1, GPR:$rs2)>;
1018 def : Pat<(add (shl GPR:$rs1, (XLenVT 3)), non_imm12:$rs2),
1019           (SH3ADD GPR:$rs1, GPR:$rs2)>;
1021 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2),
1022           (SH1ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1023 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2),
1024           (SH1ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1025 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2),
1026           (SH1ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1027 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2),
1028           (SH2ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1029 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2),
1030           (SH2ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1031 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2),
1032           (SH2ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1033 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2),
1034           (SH3ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1035 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2),
1036           (SH3ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1037 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2),
1038           (SH3ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1040 def : Pat<(add GPR:$r, CSImm12MulBy4:$i),
1041           (SH2ADD (ADDI X0, (SimmShiftRightBy2XForm CSImm12MulBy4:$i)),
1042                   GPR:$r)>;
1043 def : Pat<(add GPR:$r, CSImm12MulBy8:$i),
1044           (SH3ADD (ADDI X0, (SimmShiftRightBy3XForm CSImm12MulBy8:$i)),
1045                   GPR:$r)>;
1047 def : Pat<(mul GPR:$r, C3LeftShift:$i),
1048           (SLLI (SH1ADD GPR:$r, GPR:$r),
1049                 (TrailingZerosXForm C3LeftShift:$i))>;
1050 def : Pat<(mul GPR:$r, C5LeftShift:$i),
1051           (SLLI (SH2ADD GPR:$r, GPR:$r),
1052                 (TrailingZerosXForm C5LeftShift:$i))>;
1053 def : Pat<(mul GPR:$r, C9LeftShift:$i),
1054           (SLLI (SH3ADD GPR:$r, GPR:$r),
1055                 (TrailingZerosXForm C9LeftShift:$i))>;
1057 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
1058           (SH1ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1059 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
1060           (SH1ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1061 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
1062           (SH2ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1063 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
1064           (SH2ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1065 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
1066           (SH2ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1067 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
1068           (SH3ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1069 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
1070           (SH3ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1071 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
1072           (SH3ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1073 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
1074           (SH1ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1075 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
1076           (SH2ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1077 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
1078           (SH3ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1079 } // Predicates = [HasStdExtZba]
1081 let Predicates = [HasStdExtZba, IsRV64] in {
1082 def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
1083           (SLLIUW GPR:$rs1, uimm5:$shamt)>;
1084 def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFF), non_imm12:$rs2)),
1085           (ADDUW GPR:$rs1, GPR:$rs2)>;
1086 def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADDUW GPR:$rs, X0)>;
1088 def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 1)), non_imm12:$rs2)),
1089           (SH1ADDUW GPR:$rs1, GPR:$rs2)>;
1090 def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 2)), non_imm12:$rs2)),
1091           (SH2ADDUW GPR:$rs1, GPR:$rs2)>;
1092 def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 3)), non_imm12:$rs2)),
1093           (SH3ADDUW GPR:$rs1, GPR:$rs2)>;
1095 def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), non_imm12:$rs2)),
1096           (SH1ADDUW GPR:$rs1, GPR:$rs2)>;
1097 def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), non_imm12:$rs2)),
1098           (SH2ADDUW GPR:$rs1, GPR:$rs2)>;
1099 def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), non_imm12:$rs2)),
1100           (SH3ADDUW GPR:$rs1, GPR:$rs2)>;
1101 } // Predicates = [HasStdExtZba, IsRV64]
1103 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
1104 def : PatGprGpr<riscv_rolw, ROLW>;
1105 def : PatGprGpr<riscv_rorw, RORW>;
1106 def : PatGprImm<riscv_rorw, RORIW, uimm5>;
1107 def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
1108           (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
1109 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
1111 let Predicates = [HasStdExtZbp, IsRV64] in {
1112 def : Pat<(riscv_rorw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
1113 def : Pat<(riscv_rolw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
1114 def : PatGprGpr<riscv_grevw, GREVW>;
1115 def : PatGprGpr<riscv_gorcw, GORCW>;
1116 def : PatGprGpr<riscv_shflw, SHFLW>;
1117 def : PatGprGpr<riscv_unshflw, UNSHFLW>;
1118 def : PatGprImm<riscv_grevw, GREVIW, uimm5>;
1119 def : PatGprImm<riscv_gorcw, GORCIW, uimm5>;
1120 } // Predicates = [HasStdExtZbp, IsRV64]
1122 let Predicates = [HasStdExtZbt, IsRV64] in {
1123 def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
1124           (FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
1125 def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, GPR:$rs2),
1126           (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
1127 def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
1128           (FSRIW GPR:$rs1, GPR:$rs3, uimm5:$shamt)>;
1129 def : Pat<(riscv_fslw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
1130           (FSRIW GPR:$rs1, GPR:$rs3, (ImmSubFrom32 uimm5:$shamt))>;
1131 } // Predicates = [HasStdExtZbt, IsRV64]
1133 let Predicates = [HasStdExtZbb, IsRV64] in {
1134 def : PatGpr<riscv_clzw, CLZW>;
1135 def : PatGpr<riscv_ctzw, CTZW>;
1136 def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
1137 } // Predicates = [HasStdExtZbb, IsRV64]
1139 let Predicates = [HasStdExtZbp, IsRV64] in {
1140 def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
1141                                (and GPR:$rs1, 0x000000000000FFFF)),
1142                            i32)),
1143           (PACKW GPR:$rs1, GPR:$rs2)>;
1144 def : Pat<(i64 (or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
1145                    (srl (and GPR:$rs1, 0xFFFFFFFF), (i64 16)))),
1146           (PACKUW GPR:$rs1, GPR:$rs2)>;
1147 } // Predicates = [HasStdExtZbp, IsRV64]
1149 let Predicates = [HasStdExtZbc] in {
1150 def : PatGprGpr<int_riscv_clmul, CLMUL>;
1151 def : PatGprGpr<int_riscv_clmulh, CLMULH>;
1152 def : PatGprGpr<int_riscv_clmulr, CLMULR>;
1153 } // Predicates = [HasStdExtZbc]
1155 let Predicates = [HasStdExtZbe] in {
1156 def : PatGprGpr<riscv_bcompress, BCOMPRESS>;
1157 def : PatGprGpr<riscv_bdecompress, BDECOMPRESS>;
1158 } // Predicates = [HasStdExtZbe]
1160 let Predicates = [HasStdExtZbe, IsRV64] in {
1161 def : PatGprGpr<riscv_bcompressw, BCOMPRESSW>;
1162 def : PatGprGpr<riscv_bdecompressw, BDECOMPRESSW>;
1163 } // Predicates = [HasStdExtZbe, IsRV64]
1165 let Predicates = [HasStdExtZbr] in {
1166 def : PatGpr<int_riscv_crc32_b, CRC32B>;
1167 def : PatGpr<int_riscv_crc32_h, CRC32H>;
1168 def : PatGpr<int_riscv_crc32_w, CRC32W>;
1169 def : PatGpr<int_riscv_crc32c_b, CRC32CB>;
1170 def : PatGpr<int_riscv_crc32c_h, CRC32CH>;
1171 def : PatGpr<int_riscv_crc32c_w, CRC32CW>;
1172 } // Predicates = [HasStdExtZbr]
1174 let Predicates = [HasStdExtZbr, IsRV64] in {
1175 def : PatGpr<int_riscv_crc32_d, CRC32D>;
1176 def : PatGpr<int_riscv_crc32c_d, CRC32CD>;
1177 } // Predicates = [HasStdExtZbr, IsRV64]