[RISCV] Add another isel pattern for slliu.w.
[lldb.git] / llvm / lib / Target / RISCV / RISCVInstrInfoB.td
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.92.
11 // This version is still experimental as the 'B' extension hasn't been
12 // ratified yet.
13 //
14 //===----------------------------------------------------------------------===//
15
16 //===----------------------------------------------------------------------===//
17 // Operand and SDNode transformation definitions.
18 //===----------------------------------------------------------------------===//
19
20 def riscv_rolw : SDNode<"RISCVISD::ROLW", SDTIntShiftOp>;
21 def riscv_rorw : SDNode<"RISCVISD::RORW", SDTIntShiftOp>;
22 def riscv_fslw : SDNode<"RISCVISD::FSLW", SDTIntShiftDOp>;
23 def riscv_fsrw : SDNode<"RISCVISD::FSRW", SDTIntShiftDOp>;
24
25 def UImmLog2XLenHalfAsmOperand : AsmOperandClass {
26   let Name = "UImmLog2XLenHalf";
27   let RenderMethod = "addImmOperands";
28   let DiagnosticType = "InvalidUImmLog2XLenHalf";
29 }
30
31 def shfl_uimm : Operand<XLenVT>, ImmLeaf<XLenVT, [{
32   if (Subtarget->is64Bit())
33     return isUInt<5>(Imm);
34   return isUInt<4>(Imm);
35 }]> {
36   let ParserMatchClass = UImmLog2XLenHalfAsmOperand;
37   let DecoderMethod = "decodeUImmOperand<5>";
38   let MCOperandPredicate = [{
39     int64_t Imm;
40     if (!MCOp.evaluateAsConstantImm(Imm))
41       return false;
42     if (STI.getTargetTriple().isArch64Bit())
43       return  isUInt<5>(Imm);
44     return isUInt<4>(Imm);
45   }];
46 }
47
48
49 // Convert rotl immediate to a rotr immediate for XLen instructions.
50 def ImmROTL2R : SDNodeXForm<imm, [{
51   uint64_t XLen = Subtarget->getXLen();
52   return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N),
53                                    N->getValueType(0));
54 }]>;
55
56 // Convert rotl immediate to a rotr immediate for W instructions.
57 def ImmROTL2RW : SDNodeXForm<imm, [{
58   return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),
59                                    N->getValueType(0));
60 }]>;
61
62 // Check that it is a SLOI (Shift Left Ones Immediate).
63 def SLOIPat : PatFrag<(ops node:$A, node:$B),
64                       (or (shl node:$A, node:$B), imm), [{
65   return MatchSLOI(N);
66 }]>;
67
68 // Check that it is a SROI (Shift Right Ones Immediate).
69 def SROIPat : PatFrag<(ops node:$A, node:$B),
70                       (or (srl node:$A, node:$B), imm), [{
71   return MatchSROI(N);
72 }]>;
73
74 // Check that it is a SROIW (Shift Right Ones Immediate i32 on RV64).
75 def SROIWPat : PatFrag<(ops node:$A, node:$B),
76                        (or (srl node:$A, node:$B), imm), [{
77   return MatchSROIW(N);
78 }]>;
79
80 // Check that it is a SLLIUW (Shift Logical Left Immediate Unsigned i32
81 // on RV64).
82 def SLLIUWPat : PatFrag<(ops node:$A, node:$B),
83                         (and (shl node:$A, node:$B), imm), [{
84   return MatchSLLIUW(N);
85 }]>;
86
87 // Checks if this mask has a single 0 bit and cannot be used with ANDI.
88 def SBCLRMask : ImmLeaf<XLenVT, [{
89   if (Subtarget->is64Bit())
90     return !isInt<12>(Imm) && isPowerOf2_64(~Imm);
91   return !isInt<12>(Imm) && isPowerOf2_32(~Imm);
92 }]>;
93
94 // Checks if this mask has a single 1 bit and cannot be used with ORI/XORI.
95 def SBSETINVMask : ImmLeaf<XLenVT, [{
96   if (Subtarget->is64Bit())
97     return !isInt<12>(Imm) && isPowerOf2_64(Imm);
98   return !isInt<12>(Imm) && isPowerOf2_32(Imm);
99 }]>;
100
101 def SBCLRXForm : SDNodeXForm<imm, [{
102   // Find the lowest 0.
103   return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(),
104                                    SDLoc(N), N->getValueType(0));
105 }]>;
106
107 def SBSETINVXForm : SDNodeXForm<imm, [{
108   // Find the lowest 1.
109   return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(),
110                                    SDLoc(N), N->getValueType(0));
111 }]>;
112
113 // Similar to above, but makes sure the immediate has 33 sign bits. When used
114 // with an AND/OR/XOR where the other operand has at least 33 sign bits, the
115 // result will have 33 sign bits. This can match SBCLRIW/SBSETIW/SBINVIW.
116 def SBCLRWMask : ImmLeaf<i64, [{
117   // After checking the sign bits, truncate to 32 bits for power of 2 check.
118   return isInt<32>(Imm) && !isInt<12>(Imm) && isPowerOf2_32(~Imm);
119 }]>;
120
121 def SBSETINVWMask : ImmLeaf<i64, [{
122   return isInt<32>(Imm) && !isInt<12>(Imm) && isPowerOf2_32(Imm);
123 }]>;
124
125 //===----------------------------------------------------------------------===//
126 // Instruction class templates
127 //===----------------------------------------------------------------------===//
128
129 // Some of these templates should be moved to RISCVInstrFormats.td once the B
130 // extension has been ratified.
131
132 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
133 class RVBUnary<bits<7> funct7, bits<5> funct5, bits<3> funct3,
134                RISCVOpcode opcode, string opcodestr>
135     : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
136               opcodestr, "$rd, $rs1"> {
137   let Inst{24-20} = funct5;
138 }
139
140 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
141 class RVBALUW_ri<bits<3> funct3, string opcodestr>
142     : RVInstI<funct3, OPC_OP_IMM_32, (outs GPR:$rd),
143               (ins GPR:$rs1, simm12:$imm12), opcodestr, "$rd, $rs1, $imm12">;
144
145 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
146 class RVBShift_ri<bits<5> funct5, bits<3> funct3, RISCVOpcode opcode,
147                   string opcodestr>
148     : RVInstI<funct3, opcode, (outs GPR:$rd),
149               (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
150               "$rd, $rs1, $shamt"> {
151   bits<6> shamt;
152
153   let Inst{31-27} = funct5;
154   // NOTE: the bit op(26)=1 is used to select funnel shifts. All other
155   // shifts operations and operations that live in the encoding space
156   // of the shifts (single bit operations, grev, gorc) use op(26) = 0
157   let Inst{26} = 0;
158   let Inst{25-20} = shamt;
159 }
160
161 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
162 class RVBShiftW_ri<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode,
163                    string opcodestr>
164     : RVInstI<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1, uimm5:$shamt),
165               opcodestr, "$rd, $rs1, $shamt"> {
166   bits<5> shamt;
167
168   let Inst{31-25} = funct7;
169   let Inst{24-20} = shamt;
170 }
171
172 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
173 class RVBShfl_ri<bits<6> funct6, bits<3> funct3, RISCVOpcode opcode,
174                  string opcodestr>
175     : RVInstI<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1, shfl_uimm:$shamt),
176               opcodestr, "$rd, $rs1, $shamt"> {
177   bits<6> shamt;
178
179   let Inst{31-26} = funct6;
180   let Inst{25-20} = shamt;
181 }
182
183 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
184 class RVBTernaryR<bits<2> funct2, bits<3> funct3_b, RISCVOpcode opcode,
185                   string opcodestr, string argstr>
186     : RVInstR4<funct2, opcode, (outs GPR:$rd),
187                (ins GPR:$rs1, GPR:$rs2, GPR:$rs3), opcodestr, argstr> {
188   let Inst{14-12} = funct3_b;
189 }
190
191 // Currently used by FSRI only
192 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
193 class RVBTernaryImm6<bits<3> funct3_b, RISCVOpcode opcode,
194                      string opcodestr, string argstr>
195     : RVInstR4<0b10, opcode, (outs GPR:$rd),
196                (ins GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt),
197                opcodestr, argstr> {
198   bits<6> shamt;
199
200   // NOTE: the first argument of RVInstR4 is hardcoded to 0b10 like the other
201   // funnel shift instructions. The second bit of the argument though is
202   // overwritten by the shamt as the encoding of this particular instruction
203   // requires. This is to obtain op(26) = 1 as required by funnel shift
204   // instructions without the need of a confusing argument in the definition
205   // of the instruction.
206   let Inst{25-20} = shamt;
207   let Inst{14-12} = funct3_b;
208 }
209
210 // Currently used by FSRIW only
211 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
212 class RVBTernaryImm5<bits<2> funct2, bits<3> funct3_b, RISCVOpcode opcode,
213                      string opcodestr, string argstr>
214     : RVInstR4<funct2, opcode, (outs GPR:$rd),
215                (ins GPR:$rs1, GPR:$rs3, uimm5:$shamt), opcodestr, argstr> {
216   bits<5> shamt;
217
218   let Inst{24-20} = shamt;
219   let Inst{14-12} = funct3_b;
220 }
221
222 //===----------------------------------------------------------------------===//
223 // Instructions
224 //===----------------------------------------------------------------------===//
225
226 let Predicates = [HasStdExtZbbOrZbp] in {
227 def ANDN  : ALU_rr<0b0100000, 0b111, "andn">, Sched<[]>;
228 def ORN   : ALU_rr<0b0100000, 0b110, "orn">, Sched<[]>;
229 def XNOR  : ALU_rr<0b0100000, 0b100, "xnor">, Sched<[]>;
230 } // Predicates = [HasStdExtZbbOrZbp]
231
232 let Predicates = [HasStdExtZbb] in {
233 def SLO  : ALU_rr<0b0010000, 0b001, "slo">, Sched<[]>;
234 def SRO  : ALU_rr<0b0010000, 0b101, "sro">, Sched<[]>;
235 } // Predicates = [HasStdExtZbb]
236
237 let Predicates = [HasStdExtZbbOrZbp] in {
238 def ROL   : ALU_rr<0b0110000, 0b001, "rol">, Sched<[]>;
239 def ROR   : ALU_rr<0b0110000, 0b101, "ror">, Sched<[]>;
240 } // Predicates = [HasStdExtZbbOrZbp]
241
242 let Predicates = [HasStdExtZbs] in {
243 def SBCLR : ALU_rr<0b0100100, 0b001, "sbclr">, Sched<[]>;
244 def SBSET : ALU_rr<0b0010100, 0b001, "sbset">, Sched<[]>;
245 def SBINV : ALU_rr<0b0110100, 0b001, "sbinv">, Sched<[]>;
246 def SBEXT : ALU_rr<0b0100100, 0b101, "sbext">, Sched<[]>;
247 } // Predicates = [HasStdExtZbs]
248
249 let Predicates = [HasStdExtZbp] in {
250 def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>;
251 def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>;
252 } // Predicates = [HasStdExtZbp]
253
254 let Predicates = [HasStdExtZbb] in {
255 def SLOI : RVBShift_ri<0b00100, 0b001, OPC_OP_IMM, "sloi">, Sched<[]>;
256 def SROI : RVBShift_ri<0b00100, 0b101, OPC_OP_IMM, "sroi">, Sched<[]>;
257 } // Predicates = [HasStdExtZbb]
258
259 let Predicates = [HasStdExtZbbOrZbp] in
260 def RORI  : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">, Sched<[]>;
261
262 let Predicates = [HasStdExtZbs] in {
263 def SBCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "sbclri">, Sched<[]>;
264 def SBSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "sbseti">, Sched<[]>;
265 def SBINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "sbinvi">, Sched<[]>;
266 def SBEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "sbexti">, Sched<[]>;
267 } // Predicates = [HasStdExtZbs]
268
269 let Predicates = [HasStdExtZbp] in {
270 def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">, Sched<[]>;
271 def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">, Sched<[]>;
272 } // Predicates = [HasStdExtZbp]
273
274 let Predicates = [HasStdExtZbt] in {
275 def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
276            Sched<[]>;
277 def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
278            Sched<[]>;
279 def FSL  : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
280            Sched<[]>;
281 def FSR  : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
282            Sched<[]>;
283 def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
284                           "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
285 } // Predicates = [HasStdExtZbt]
286
287 let Predicates = [HasStdExtZbb] in {
288 def CLZ  : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0010011>, "clz">,
289            Sched<[]>;
290 def CTZ  : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0010011>, "ctz">,
291            Sched<[]>;
292 def PCNT : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0010011>, "pcnt">,
293            Sched<[]>;
294 } // Predicates = [HasStdExtZbb]
295
296 let Predicates = [HasStdExtZbm, IsRV64] in
297 def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, RISCVOpcode<0b0010011>,
298                         "bmatflip">, Sched<[]>;
299
300 let Predicates = [HasStdExtZbb] in {
301 def SEXTB : RVBUnary<0b0110000, 0b00100, 0b001, RISCVOpcode<0b0010011>,
302                      "sext.b">, Sched<[]>;
303 def SEXTH : RVBUnary<0b0110000, 0b00101, 0b001, RISCVOpcode<0b0010011>,
304                      "sext.h">, Sched<[]>;
305 } // Predicates = [HasStdExtZbb]
306
307 let Predicates = [HasStdExtZbr] in {
308 def CRC32B : RVBUnary<0b0110000, 0b10000, 0b001, RISCVOpcode<0b0010011>,
309                       "crc32.b">, Sched<[]>;
310 def CRC32H : RVBUnary<0b0110000, 0b10001, 0b001, RISCVOpcode<0b0010011>,
311                       "crc32.h">, Sched<[]>;
312 def CRC32W : RVBUnary<0b0110000, 0b10010, 0b001, RISCVOpcode<0b0010011>,
313                       "crc32.w">, Sched<[]>;
314 } // Predicates = [HasStdExtZbr]
315
316 let Predicates = [HasStdExtZbr, IsRV64] in
317 def CRC32D  : RVBUnary<0b0110000, 0b10011, 0b001, RISCVOpcode<0b0010011>,
318                        "crc32.d">, Sched<[]>;
319
320 let Predicates = [HasStdExtZbr] in {
321 def CRC32CB : RVBUnary<0b0110000, 0b11000, 0b001, RISCVOpcode<0b0010011>,
322                        "crc32c.b">, Sched<[]>;
323 def CRC32CH : RVBUnary<0b0110000, 0b11001, 0b001, RISCVOpcode<0b0010011>,
324                        "crc32c.h">, Sched<[]>;
325 def CRC32CW : RVBUnary<0b0110000, 0b11010, 0b001, RISCVOpcode<0b0010011>,
326                        "crc32c.w">, Sched<[]>;
327 } // Predicates = [HasStdExtZbr]
328
329 let Predicates = [HasStdExtZbr, IsRV64] in
330 def CRC32CD : RVBUnary<0b0110000, 0b11011, 0b001, RISCVOpcode<0b0010011>,
331                        "crc32c.d">, Sched<[]>;
332
333 let Predicates = [HasStdExtZbc] in {
334 def CLMUL  : ALU_rr<0b0000101, 0b001, "clmul">, Sched<[]>;
335 def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">, Sched<[]>;
336 def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh">, Sched<[]>;
337 } // Predicates = [HasStdExtZbc]
338
339 let Predicates = [HasStdExtZbb] in {
340 def MIN  : ALU_rr<0b0000101, 0b100, "min">, Sched<[]>;
341 def MAX  : ALU_rr<0b0000101, 0b101, "max">, Sched<[]>;
342 def MINU : ALU_rr<0b0000101, 0b110, "minu">, Sched<[]>;
343 def MAXU : ALU_rr<0b0000101, 0b111, "maxu">, Sched<[]>;
344 } // Predicates = [HasStdExtZbb]
345
346 let Predicates = [HasStdExtZbp] in {
347 def SHFL   : ALU_rr<0b0000100, 0b001, "shfl">, Sched<[]>;
348 def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">, Sched<[]>;
349 } // Predicates = [HasStdExtZbp]
350
351 let Predicates = [HasStdExtZbe] in {
352 def BDEP : ALU_rr<0b0100100, 0b110, "bdep">, Sched<[]>;
353 def BEXT : ALU_rr<0b0000100, 0b110, "bext">, Sched<[]>;
354 } // Predicates = [HasStdExtZbe]
355
356 let Predicates = [HasStdExtZbbOrZbp] in {
357 def PACK  : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>;
358 def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>;
359 } // Predicates = [HasStdExtZbbOrZbp]
360
361 let Predicates = [HasStdExtZbm, IsRV64] in {
362 def BMATOR   : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>;
363 def BMATXOR  : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>;
364 } // Predicates = [HasStdExtZbm, IsRV64]
365
366 let Predicates = [HasStdExtZbbOrZbp] in
367 def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
368
369 let Predicates = [HasStdExtZbf] in
370 def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>;
371
372 let Predicates = [HasStdExtZbp] in {
373 def SHFLI   : RVBShfl_ri<0b000010, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>;
374 def UNSHFLI : RVBShfl_ri<0b000010, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>;
375 } // Predicates = [HasStdExtZbp]
376
377 let Predicates = [HasStdExtZbb, IsRV64] in {
378 def ADDIWU : RVBALUW_ri<0b100, "addiwu">, Sched<[]>;
379 def SLLIUW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slliu.w">, Sched<[]>;
380 def ADDWU : ALUW_rr<0b0000101, 0b000, "addwu">, Sched<[]>;
381 def SUBWU : ALUW_rr<0b0100101, 0b000, "subwu">, Sched<[]>;
382 def ADDUW : ALUW_rr<0b0000100, 0b000, "addu.w">, Sched<[]>;
383 def SUBUW : ALUW_rr<0b0100100, 0b000, "subu.w">, Sched<[]>;
384 } // Predicates = [HasStdExtZbb, IsRV64]
385
386 let Predicates = [HasStdExtZbb, IsRV64] in {
387 def SLOW   : ALUW_rr<0b0010000, 0b001, "slow">, Sched<[]>;
388 def SROW   : ALUW_rr<0b0010000, 0b101, "srow">, Sched<[]>;
389 } // Predicates = [HasStdExtZbb, IsRV64]
390
391 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
392 def ROLW  : ALUW_rr<0b0110000, 0b001, "rolw">, Sched<[]>;
393 def RORW  : ALUW_rr<0b0110000, 0b101, "rorw">, Sched<[]>;
394 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
395
396 let Predicates = [HasStdExtZbs, IsRV64] in {
397 def SBCLRW : ALUW_rr<0b0100100, 0b001, "sbclrw">, Sched<[]>;
398 def SBSETW : ALUW_rr<0b0010100, 0b001, "sbsetw">, Sched<[]>;
399 def SBINVW : ALUW_rr<0b0110100, 0b001, "sbinvw">, Sched<[]>;
400 def SBEXTW : ALUW_rr<0b0100100, 0b101, "sbextw">, Sched<[]>;
401 } // Predicates = [HasStdExtZbs, IsRV64]
402
403 let Predicates = [HasStdExtZbp, IsRV64] in {
404 def GORCW  : ALUW_rr<0b0010100, 0b101, "gorcw">, Sched<[]>;
405 def GREVW  : ALUW_rr<0b0110100, 0b101, "grevw">, Sched<[]>;
406 } // Predicates = [HasStdExtZbp, IsRV64]
407
408 let Predicates = [HasStdExtZbb, IsRV64] in {
409 def SLOIW  : RVBShiftW_ri<0b0010000, 0b001, OPC_OP_IMM_32, "sloiw">, Sched<[]>;
410 def SROIW  : RVBShiftW_ri<0b0010000, 0b101, OPC_OP_IMM_32, "sroiw">, Sched<[]>;
411 } // Predicates = [HasStdExtZbb, IsRV64]
412
413 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
414 def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">, Sched<[]>;
415
416 let Predicates = [HasStdExtZbs, IsRV64] in {
417 def SBCLRIW : RVBShiftW_ri<0b0100100, 0b001, OPC_OP_IMM_32, "sbclriw">,
418               Sched<[]>;
419 def SBSETIW : RVBShiftW_ri<0b0010100, 0b001, OPC_OP_IMM_32, "sbsetiw">,
420               Sched<[]>;
421 def SBINVIW : RVBShiftW_ri<0b0110100, 0b001, OPC_OP_IMM_32, "sbinviw">,
422               Sched<[]>;
423 } // Predicates = [HasStdExtZbs, IsRV64]
424
425 let Predicates = [HasStdExtZbp, IsRV64] in {
426 def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">, Sched<[]>;
427 def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">, Sched<[]>;
428 } // Predicates = [HasStdExtZbp, IsRV64]
429
430 let Predicates = [HasStdExtZbt, IsRV64] in {
431 def FSLW  : RVBTernaryR<0b10, 0b001, OPC_OP_32,
432                         "fslw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
433 def FSRW  : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
434                         "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
435 def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
436                            "fsriw", "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
437 } // Predicates = [HasStdExtZbt, IsRV64]
438
439 let Predicates = [HasStdExtZbb, IsRV64] in {
440 def CLZW   : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0011011>,
441                       "clzw">, Sched<[]>;
442 def CTZW   : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0011011>,
443                       "ctzw">, Sched<[]>;
444 def PCNTW  : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0011011>,
445                       "pcntw">, Sched<[]>;
446 } // Predicates = [HasStdExtZbb, IsRV64]
447
448 let Predicates = [HasStdExtZbc, IsRV64] in {
449 def CLMULW  : ALUW_rr<0b0000101, 0b001, "clmulw">, Sched<[]>;
450 def CLMULRW : ALUW_rr<0b0000101, 0b010, "clmulrw">, Sched<[]>;
451 def CLMULHW : ALUW_rr<0b0000101, 0b011, "clmulhw">, Sched<[]>;
452 } // Predicates = [HasStdExtZbc, IsRV64]
453
454 let Predicates = [HasStdExtZbp, IsRV64] in {
455 def SHFLW   : ALUW_rr<0b0000100, 0b001, "shflw">, Sched<[]>;
456 def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">, Sched<[]>;
457 } // Predicates = [HasStdExtZbp, IsRV64]
458
459 let Predicates = [HasStdExtZbe, IsRV64] in {
460 def BDEPW : ALUW_rr<0b0100100, 0b110, "bdepw">, Sched<[]>;
461 def BEXTW : ALUW_rr<0b0000100, 0b110, "bextw">, Sched<[]>;
462 } // Predicates = [HasStdExtZbe, IsRV64]
463
464 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
465 def PACKW  : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>;
466 def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
467 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
468
469 let Predicates = [HasStdExtZbf, IsRV64] in
470 def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>;
471
472 //===----------------------------------------------------------------------===//
473 // Future compressed instructions
474 //===----------------------------------------------------------------------===//
475
476 // The presence of these instructions in the B extension is purely experimental
477 // and they should be moved to the C extension as soon as they are ratified.
478
479 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
480 class RVBInstC<bits<2> funct2, string opcodestr>
481     : RVInst16<(outs GPRC:$rs_wb), (ins GPRC:$rs), opcodestr, "$rs", [],
482                InstFormatCR> {
483   bits<3> rs;
484   let Constraints = "$rs = $rs_wb";
485
486   let Inst{15-12} = 0b0110;
487   let Inst{11-10} = funct2;
488   let Inst{9-7} = rs;
489   let Inst{6-0} = 0b0000001;
490 }
491
492 // The namespace RVBC exists to avoid encoding conflicts with the compressed
493 // instructions c.addi16sp and c.lui already implemented in the C extension.
494
495 let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC] in {
496 def C_NOT : RVBInstC<0b00, "c.not">, Sched<[]>;
497 def C_NEG : RVBInstC<0b01, "c.neg">, Sched<[]>;
498 } // DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC]
499
500 let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtZbbOrZbp, HasStdExtC, IsRV64] in
501 def C_ZEXTW : RVBInstC<0b10, "c.zext.w">, Sched<[]>;
502
503 //===----------------------------------------------------------------------===//
504 // Pseudo Instructions
505 //===----------------------------------------------------------------------===//
506
507 let Predicates = [HasStdExtZbb, IsRV32] in {
508 def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;
509 } // Predicates = [HasStdExtZbb, IsRV32]
510
511 let Predicates = [HasStdExtZbb, IsRV64] in {
512 def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>;
513 def : InstAlias<"zext.w $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;
514 } // Predicates = [HasStdExtZbb, IsRV64]
515
516 let Predicates = [HasStdExtZbp] in {
517 def : InstAlias<"rev.p $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00001)>;
518 def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>;
519 def : InstAlias<"rev.n $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00011)>;
520 def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>;
521 def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>;
522 def : InstAlias<"rev.b $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00111)>;
523 def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>;
524 def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>;
525 def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>;
526 def : InstAlias<"rev.h $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b01111)>;
527
528 def : InstAlias<"zip.n $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0001)>;
529 def : InstAlias<"unzip.n $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>;
530 def : InstAlias<"zip2.b $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0010)>;
531 def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>;
532 def : InstAlias<"zip.b $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0011)>;
533 def : InstAlias<"unzip.b $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>;
534 def : InstAlias<"zip4.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0100)>;
535 def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>;
536 def : InstAlias<"zip2.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0110)>;
537 def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>;
538 def : InstAlias<"zip.h $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0111)>;
539 def : InstAlias<"unzip.h $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>;
540
541 def : InstAlias<"orc.p $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00001)>;
542 def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>;
543 def : InstAlias<"orc.n $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00011)>;
544 def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>;
545 def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>;
546 def : InstAlias<"orc.b $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00111)>;
547 def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>;
548 def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>;
549 def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>;
550 def : InstAlias<"orc.h $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b01111)>;
551 } // Predicates = [HasStdExtZbp]
552
553 let Predicates = [HasStdExtZbp, IsRV32] in {
554 def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>;
555 def : InstAlias<"rev8 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11000)>;
556 def : InstAlias<"rev4 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11100)>;
557 def : InstAlias<"rev2 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11110)>;
558 def : InstAlias<"rev $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b11111)>;
559
560 def : InstAlias<"zip8 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1000)>;
561 def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>;
562 def : InstAlias<"zip4 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1100)>;
563 def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>;
564 def : InstAlias<"zip2 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1110)>;
565 def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>;
566 def : InstAlias<"zip $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b1111)>;
567 def : InstAlias<"unzip $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b1111)>;
568
569 def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>;
570 def : InstAlias<"orc8 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11000)>;
571 def : InstAlias<"orc4 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11100)>;
572 def : InstAlias<"orc2 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11110)>;
573 def : InstAlias<"orc $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b11111)>;
574 } // Predicates = [HasStdExtZbp, IsRV32]
575
576 let Predicates = [HasStdExtZbp, IsRV64] in {
577 def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>;
578 def : InstAlias<"rev8.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011000)>;
579 def : InstAlias<"rev4.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011100)>;
580 def : InstAlias<"rev2.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011110)>;
581 def : InstAlias<"rev.w $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b011111)>;
582 def : InstAlias<"rev32 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b100000)>;
583 def : InstAlias<"rev16 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b110000)>;
584 def : InstAlias<"rev8 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111000)>;
585 def : InstAlias<"rev4 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111100)>;
586 def : InstAlias<"rev2 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111110)>;
587 def : InstAlias<"rev $rd, $rs",     (GREVI GPR:$rd, GPR:$rs, 0b111111)>;
588
589 def : InstAlias<"zip8.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01000)>;
590 def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>;
591 def : InstAlias<"zip4.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01100)>;
592 def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>;
593 def : InstAlias<"zip2.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01110)>;
594 def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>;
595 def : InstAlias<"zip.w $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b01111)>;
596 def : InstAlias<"unzip.w $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>;
597 def : InstAlias<"zip16 $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b10000)>;
598 def : InstAlias<"unzip16 $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>;
599 def : InstAlias<"zip8 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11000)>;
600 def : InstAlias<"unzip8 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>;
601 def : InstAlias<"zip4 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11100)>;
602 def : InstAlias<"unzip4 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>;
603 def : InstAlias<"zip2 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11110)>;
604 def : InstAlias<"unzip2 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>;
605 def : InstAlias<"zip $rd, $rs",      (SHFLI   GPR:$rd, GPR:$rs, 0b11111)>;
606 def : InstAlias<"unzip $rd, $rs",    (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>;
607
608 def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>;
609 def : InstAlias<"orc8.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011000)>;
610 def : InstAlias<"orc4.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011100)>;
611 def : InstAlias<"orc2.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011110)>;
612 def : InstAlias<"orc.w $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b011111)>;
613 def : InstAlias<"orc32 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b100000)>;
614 def : InstAlias<"orc16 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b110000)>;
615 def : InstAlias<"orc8 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111000)>;
616 def : InstAlias<"orc4 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111100)>;
617 def : InstAlias<"orc2 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111110)>;
618 def : InstAlias<"orc $rd, $rs",     (GORCI GPR:$rd, GPR:$rs, 0b111111)>;
619 } // Predicates = [HasStdExtZbp, IsRV64]
620
621 //===----------------------------------------------------------------------===//
622 // Compressed Instruction patterns
623 //===----------------------------------------------------------------------===//
624 let Predicates = [HasStdExtZbproposedc, HasStdExtC] in {
625 def : CompressPat<(XORI GPRC:$rs1, GPRC:$rs1, -1),
626                   (C_NOT GPRC:$rs1)>;
627 def : CompressPat<(SUB GPRC:$rs1, X0, GPRC:$rs1),
628                   (C_NEG GPRC:$rs1)>;
629 } // Predicates = [HasStdExtZbproposedc, HasStdExtC]
630
631 let Predicates = [HasStdExtZbproposedc, HasStdExtZbbOrZbp, HasStdExtC, IsRV64] in {
632 def : CompressPat<(PACK GPRC:$rs1, GPRC:$rs1, X0),
633                   (C_ZEXTW GPRC:$rs1)>;
634 } // Predicates = [HasStdExtZbproposedc, HasStdExtC, IsRV64]
635
636 //===----------------------------------------------------------------------===//
637 // Codegen patterns
638 //===----------------------------------------------------------------------===//
639
640 let Predicates = [HasStdExtZbbOrZbp] in {
641 def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
642 def : Pat<(or  GPR:$rs1, (not GPR:$rs2)), (ORN  GPR:$rs1, GPR:$rs2)>;
643 def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
644 } // Predicates = [HasStdExtZbbOrZbp]
645
646 let Predicates = [HasStdExtZbb] in {
647 def : Pat<(not (shl (not GPR:$rs1), GPR:$rs2)),
648           (SLO GPR:$rs1, GPR:$rs2)>;
649 def : Pat<(not (srl (not GPR:$rs1), GPR:$rs2)),
650           (SRO GPR:$rs1, GPR:$rs2)>;
651 } // Predicates = [HasStdExtZbb]
652
653 let Predicates = [HasStdExtZbbOrZbp] in {
654 def : Pat<(rotl GPR:$rs1, GPR:$rs2), (ROL GPR:$rs1, GPR:$rs2)>;
655 def : Pat<(rotr GPR:$rs1, GPR:$rs2), (ROR GPR:$rs1, GPR:$rs2)>;
656 } // Predicates = [HasStdExtZbbOrZbp]
657
658 let Predicates = [HasStdExtZbs] in {
659 def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
660           (SBCLR GPR:$rs1, GPR:$rs2)>;
661 def : Pat<(and (rotl -2, GPR:$rs2), GPR:$rs1), (SBCLR GPR:$rs1, GPR:$rs2)>;
662 def : Pat<(or (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
663           (SBSET GPR:$rs1, GPR:$rs2)>;
664 def : Pat<(xor (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
665           (SBINV GPR:$rs1, GPR:$rs2)>;
666 def : Pat<(and (shiftop<srl> GPR:$rs1, GPR:$rs2), 1),
667           (SBEXT GPR:$rs1, GPR:$rs2)>;
668
669 def : Pat<(shiftop<shl> 1, GPR:$rs2),
670           (SBSET X0, GPR:$rs2)>;
671
672 def : Pat<(and GPR:$rs1, SBCLRMask:$mask),
673           (SBCLRI GPR:$rs1, (SBCLRXForm imm:$mask))>;
674 def : Pat<(or GPR:$rs1, SBSETINVMask:$mask),
675           (SBSETI GPR:$rs1, (SBSETINVXForm imm:$mask))>;
676 def : Pat<(xor GPR:$rs1, SBSETINVMask:$mask),
677           (SBINVI GPR:$rs1, (SBSETINVXForm imm:$mask))>;
678 }
679
680 let Predicates = [HasStdExtZbb] in {
681 def : Pat<(SLOIPat GPR:$rs1, uimmlog2xlen:$shamt),
682           (SLOI GPR:$rs1, uimmlog2xlen:$shamt)>;
683 def : Pat<(SROIPat GPR:$rs1, uimmlog2xlen:$shamt),
684           (SROI GPR:$rs1, uimmlog2xlen:$shamt)>;
685 } // Predicates = [HasStdExtZbb]
686
687 // There's no encoding for roli in the current version of the 'B' extension
688 // (v0.92) as it can be implemented with rori by negating the immediate.
689 let Predicates = [HasStdExtZbbOrZbp] in {
690 def : Pat<(rotr GPR:$rs1, uimmlog2xlen:$shamt),
691           (RORI GPR:$rs1, uimmlog2xlen:$shamt)>;
692 def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
693           (RORI GPR:$rs1, (ImmROTL2R uimmlog2xlen:$shamt))>;
694 }
695
696 // We don't pattern-match sbclri[w], sbseti[w], sbinvi[w] because they are
697 // pattern-matched by simple andi, ori, and xori.
698 let Predicates = [HasStdExtZbs] in
699 def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)),
700           (SBEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
701
702 def riscv_grevi    : SDNode<"RISCVISD::GREVI", SDTIntBinOp, []>;
703 def riscv_greviw   : SDNode<"RISCVISD::GREVIW", SDTIntBinOp, []>;
704 def riscv_gorci    : SDNode<"RISCVISD::GORCI", SDTIntBinOp, []>;
705 def riscv_gorciw   : SDNode<"RISCVISD::GORCIW", SDTIntBinOp, []>;
706
707 let Predicates = [HasStdExtZbp] in {
708 def : Pat<(riscv_grevi GPR:$rs1, timm:$shamt), (GREVI GPR:$rs1, timm:$shamt)>;
709 def : Pat<(riscv_gorci GPR:$rs1, timm:$shamt), (GORCI GPR:$rs1, timm:$shamt)>;
710 } // Predicates = [HasStdExtZbp]
711
712 let Predicates = [HasStdExtZbp, IsRV32] in {
713 def : Pat<(rotr (riscv_grevi GPR:$rs1, (i32 24)), (i32 16)), (GREVI GPR:$rs1, 8)>;
714 def : Pat<(rotl (riscv_grevi GPR:$rs1, (i32 24)), (i32 16)), (GREVI GPR:$rs1, 8)>;
715 } // Predicates = [HasStdExtZbp, IsRV32]
716
717 let Predicates = [HasStdExtZbt] in {
718 def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)),
719           (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
720 def : Pat<(riscv_selectcc GPR:$rs2, (XLenVT 0), (XLenVT 17), GPR:$rs3, GPR:$rs1),
721           (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
722 } // Predicates = [HasStdExtZbt]
723
724 // fshl and fshr concatenate their operands in the same order. fsr and fsl
725 // instruction use different orders. fshl will return its first operand for
726 // shift of zero, fshr will return its second operand. fsl and fsr both return
727 // $rs1 so the patterns need to have different operand orders.
728 //
729 // fshl and fshr only read the lower log2(xlen) bits of the shift amount, but
730 // fsl/fsr instructions read log2(xlen)+1 bits. DAG combine may have removed
731 // an AND mask on the shift amount that we need to add back to avoid a one in
732 // the extra bit.
733 // FIXME: If we can prove that the extra bit in the shift amount is zero, we
734 // don't need this mask.
735 let Predicates = [HasStdExtZbt, IsRV32] in {
736 def : Pat<(fshl GPR:$rs1, GPR:$rs3, GPR:$rs2),
737           (FSL GPR:$rs1, (ANDI GPR:$rs2, 31), GPR:$rs3)>;
738 def : Pat<(fshr GPR:$rs3, GPR:$rs1, GPR:$rs2),
739           (FSR GPR:$rs1, (ANDI GPR:$rs2, 31), GPR:$rs3)>;
740 }
741 let Predicates = [HasStdExtZbt, IsRV64] in {
742 def : Pat<(fshl GPR:$rs1, GPR:$rs3, GPR:$rs2),
743           (FSL GPR:$rs1, (ANDI GPR:$rs2, 63), GPR:$rs3)>;
744 def : Pat<(fshr GPR:$rs3, GPR:$rs1, GPR:$rs2),
745           (FSR GPR:$rs1, (ANDI GPR:$rs2, 63), GPR:$rs3)>;
746 }
747 let Predicates = [HasStdExtZbt] in {
748 def : Pat<(fshr GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
749           (FSRI GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt)>;
750 // We can use FSRI for fshl by immediate if we subtract the immediate from
751 // XLen and swap the operands.
752 def : Pat<(fshl GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
753           (FSRI GPR:$rs1, GPR:$rs3, (ImmROTL2R uimmlog2xlen:$shamt))>;
754 } // Predicates = [HasStdExtZbt]
755
756 let Predicates = [HasStdExtZbb] in {
757 def : Pat<(ctlz GPR:$rs1), (CLZ GPR:$rs1)>;
758 def : Pat<(cttz GPR:$rs1), (CTZ GPR:$rs1)>;
759 def : Pat<(ctpop GPR:$rs1), (PCNT GPR:$rs1)>;
760 } // Predicates = [HasStdExtZbb]
761
762 let Predicates = [HasStdExtZbb] in {
763 def : Pat<(sext_inreg GPR:$rs1, i8), (SEXTB GPR:$rs1)>;
764 def : Pat<(sext_inreg GPR:$rs1, i16), (SEXTH GPR:$rs1)>;
765 }
766
767 let Predicates = [HasStdExtZbb] in {
768 def : Pat<(smin GPR:$rs1, GPR:$rs2), (MIN  GPR:$rs1, GPR:$rs2)>;
769 def : Pat<(smax GPR:$rs1, GPR:$rs2), (MAX  GPR:$rs1, GPR:$rs2)>;
770 def : Pat<(umin GPR:$rs1, GPR:$rs2), (MINU GPR:$rs1, GPR:$rs2)>;
771 def : Pat<(umax GPR:$rs1, GPR:$rs2), (MAXU GPR:$rs1, GPR:$rs2)>;
772 } // Predicates = [HasStdExtZbb]
773
774 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
775 def : Pat<(or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16))),
776           (PACK GPR:$rs1, GPR:$rs2)>;
777 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
778 def : Pat<(or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32))),
779           (PACK GPR:$rs1, GPR:$rs2)>;
780 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
781 def : Pat<(or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16))),
782           (PACKU GPR:$rs1, GPR:$rs2)>;
783 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
784 def : Pat<(or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32))),
785           (PACKU GPR:$rs1, GPR:$rs2)>;
786 let Predicates = [HasStdExtZbbOrZbp] in
787 def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFF00),
788               (and GPR:$rs1, 0x00FF)),
789           (PACKH GPR:$rs1, GPR:$rs2)>;
790
791 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
792 def : Pat<(and GPR:$rs, 0x0000FFFF), (PACK GPR:$rs, X0)>;
793 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
794 def : Pat<(and GPR:$rs, 0x000000000000FFFF), (PACKW GPR:$rs, X0)>;
795 def : Pat<(and GPR:$rs, 0x00000000FFFFFFFF), (PACK GPR:$rs, X0)>;
796 }
797
798 let Predicates = [HasStdExtZbp, IsRV32] in {
799 def : Pat<(or (or (and (shl GPR:$rs1, (i32 8)), (i32 0x00FF0000)),
800                   (and GPR:$rs1, (i32 0xFF0000FF))),
801               (and (srl GPR:$rs1, (i32 8)), (i32 0x0000FF00))),
802           (SHFLI GPR:$rs1, (i32 8))>;
803 def : Pat<(or (or (and (shl GPR:$rs1, (i32 4)), (i32 0x0F000F00)),
804                   (and GPR:$rs1, (i32 0xF00FF00F))),
805               (and (srl GPR:$rs1, (i32 4)), (i32 0x00F000F0))),
806           (SHFLI GPR:$rs1, (i32 4))>;
807 def : Pat<(or (or (and (shl GPR:$rs1, (i32 2)), (i32 0x30303030)),
808                   (and GPR:$rs1, (i32 0xC3C3C3C3))),
809               (and (srl GPR:$rs1, (i32 2)), (i32 0x0C0C0C0C))),
810           (SHFLI GPR:$rs1, (i32 2))>;
811 def : Pat<(or (or (and (shl GPR:$rs1, (i32 1)), (i32 0x44444444)),
812                   (and GPR:$rs1, (i32 0x99999999))),
813               (and (srl GPR:$rs1, (i32 1)), (i32 0x22222222))),
814           (SHFLI GPR:$rs1, (i32 1))>;
815 } // Predicates = [HasStdExtZbp, IsRV32]
816
817 let Predicates = [HasStdExtZbp, IsRV64] in {
818 def : Pat<(or (or (and (shl GPR:$rs1, (i64 16)), (i64 0x0000FFFF00000000)),
819                   (and GPR:$rs1, (i64 0xFFFF00000000FFFF))),
820               (and (srl GPR:$rs1, (i64 16)), (i64 0x00000000FFFF0000))),
821           (SHFLI GPR:$rs1, (i64 16))>;
822 def : Pat<(or (or (and (shl GPR:$rs1, (i64 8)), (i64 0x00FF000000FF0000)),
823                   (and GPR:$rs1, (i64 0xFF0000FFFF0000FF))),
824               (and (srl GPR:$rs1, (i64 8)), (i64 0x0000FF000000FF00))),
825           (SHFLI GPR:$rs1, (i64 8))>;
826 def : Pat<(or (or (and (shl GPR:$rs1, (i64 4)), (i64 0x0F000F000F000F00)),
827                   (and GPR:$rs1, (i64 0xF00FF00FF00FF00F))),
828               (and (srl GPR:$rs1, (i64 4)), (i64 0x00F000F000F000F0))),
829           (SHFLI GPR:$rs1, (i64 4))>;
830 def : Pat<(or (or (and (shl GPR:$rs1, (i64 2)), (i64 0x3030303030303030)),
831                   (and GPR:$rs1, (i64 0xC3C3C3C3C3C3C3C3))),
832               (and (srl GPR:$rs1, (i64 2)), (i64 0x0C0C0C0C0C0C0C0C))),
833           (SHFLI GPR:$rs1, (i64 2))>;
834 def : Pat<(or (or (and (shl GPR:$rs1, (i64 1)), (i64 0x4444444444444444)),
835                   (and GPR:$rs1, (i64 0x9999999999999999))),
836               (and (srl GPR:$rs1, (i64 1)), (i64 0x2222222222222222))),
837           (SHFLI GPR:$rs1, (i64 1))>;
838 } // Predicates = [HasStdExtZbp, IsRV64]
839
840 let Predicates = [HasStdExtZbb, IsRV64] in {
841 def : Pat<(and (add GPR:$rs, simm12:$simm12), (i64 0xFFFFFFFF)),
842           (ADDIWU GPR:$rs, simm12:$simm12)>;
843 def : Pat<(SLLIUWPat GPR:$rs1, uimm5:$shamt),
844           (SLLIUW GPR:$rs1, uimm5:$shamt)>;
845 def : Pat<(shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt),
846           (SLLIUW GPR:$rs1, uimm5:$shamt)>;
847 def : Pat<(and (add GPR:$rs1, GPR:$rs2), (i64 0xFFFFFFFF)),
848           (ADDWU GPR:$rs1, GPR:$rs2)>;
849 def : Pat<(and (sub GPR:$rs1, GPR:$rs2), (i64 0xFFFFFFFF)),
850           (SUBWU GPR:$rs1, GPR:$rs2)>;
851 def : Pat<(add GPR:$rs1, (and GPR:$rs2, (i64 0xFFFFFFFF))),
852           (ADDUW GPR:$rs1, GPR:$rs2)>;
853 def : Pat<(sub GPR:$rs1, (and GPR:$rs2, (i64 0xFFFFFFFF))),
854           (SUBUW GPR:$rs1, GPR:$rs2)>;
855 def : Pat<(not (riscv_sllw (not GPR:$rs1), GPR:$rs2)),
856           (SLOW GPR:$rs1, GPR:$rs2)>;
857 def : Pat<(not (riscv_srlw (not GPR:$rs1), GPR:$rs2)),
858           (SROW GPR:$rs1, GPR:$rs2)>;
859 } // Predicates = [HasStdExtZbb, IsRV64]
860
861 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
862 def : Pat<(riscv_rolw GPR:$rs1, GPR:$rs2),
863           (ROLW GPR:$rs1, GPR:$rs2)>;
864 def : Pat<(riscv_rorw GPR:$rs1, GPR:$rs2),
865           (RORW GPR:$rs1, GPR:$rs2)>;
866 def : Pat<(riscv_rorw GPR:$rs1, uimm5:$rs2),
867           (RORIW GPR:$rs1, uimm5:$rs2)>;
868 def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
869           (RORIW GPR:$rs1, (ImmROTL2RW uimm5:$rs2))>;
870 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
871
872 let Predicates = [HasStdExtZbs, IsRV64] in {
873 def : Pat<(and (not (riscv_sllw 1, GPR:$rs2)), (assertsexti32 GPR:$rs1)),
874           (SBCLRW GPR:$rs1, GPR:$rs2)>;
875 def : Pat<(sext_inreg (and (not (riscv_sllw 1, GPR:$rs2)), GPR:$rs1), i32),
876           (SBCLRW GPR:$rs1, GPR:$rs2)>;
877 def : Pat<(or (riscv_sllw 1, GPR:$rs2), (assertsexti32 GPR:$rs1)),
878           (SBSETW GPR:$rs1, GPR:$rs2)>;
879 def : Pat<(sext_inreg (or (riscv_sllw 1, GPR:$rs2), GPR:$rs1), i32),
880           (SBSETW GPR:$rs1, GPR:$rs2)>;
881 def : Pat<(xor (riscv_sllw 1, GPR:$rs2), (assertsexti32 GPR:$rs1)),
882           (SBINVW GPR:$rs1, GPR:$rs2)>;
883 def : Pat<(sext_inreg (xor (riscv_sllw 1, GPR:$rs2), GPR:$rs1), i32),
884           (SBINVW GPR:$rs1, GPR:$rs2)>;
885 def : Pat<(and (riscv_srlw GPR:$rs1, GPR:$rs2), 1),
886           (SBEXTW GPR:$rs1, GPR:$rs2)>;
887
888 def : Pat<(riscv_sllw 1, GPR:$rs2),
889           (SBSETW X0, GPR:$rs2)>;
890
891 def : Pat<(and (assertsexti32 GPR:$rs1), SBCLRWMask:$mask),
892           (SBCLRIW GPR:$rs1, (SBCLRXForm imm:$mask))>;
893 def : Pat<(or (assertsexti32 GPR:$rs1), SBSETINVWMask:$mask),
894           (SBSETIW GPR:$rs1, (SBSETINVXForm imm:$mask))>;
895 def : Pat<(xor (assertsexti32 GPR:$rs1), SBSETINVWMask:$mask),
896           (SBINVIW GPR:$rs1, (SBSETINVXForm imm:$mask))>;
897
898 } // Predicates = [HasStdExtZbs, IsRV64]
899
900 let Predicates = [HasStdExtZbb, IsRV64] in {
901 def : Pat<(sext_inreg (SLOIPat GPR:$rs1, uimm5:$shamt), i32),
902           (SLOIW GPR:$rs1, uimm5:$shamt)>;
903 def : Pat<(SROIWPat GPR:$rs1, uimm5:$shamt),
904           (SROIW GPR:$rs1, uimm5:$shamt)>;
905 } // Predicates = [HasStdExtZbb, IsRV64]
906
907 let Predicates = [HasStdExtZbp, IsRV64] in {
908 def : Pat<(riscv_rorw (riscv_greviw GPR:$rs1, 24), (i64 16)), (GREVIW GPR:$rs1, 8)>;
909 def : Pat<(riscv_rolw (riscv_greviw GPR:$rs1, 24), (i64 16)), (GREVIW GPR:$rs1, 8)>;
910 def : Pat<(riscv_greviw GPR:$rs1, timm:$shamt), (GREVIW GPR:$rs1, timm:$shamt)>;
911 def : Pat<(riscv_gorciw GPR:$rs1, timm:$shamt), (GORCIW GPR:$rs1, timm:$shamt)>;
912 } // Predicates = [HasStdExtZbp, IsRV64]
913
914 let Predicates = [HasStdExtZbt, IsRV64] in {
915 def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
916           (FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
917 def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, GPR:$rs2),
918           (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
919 def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
920           (FSRIW GPR:$rs1, GPR:$rs3, uimm5:$shamt)>;
921 def : Pat<(riscv_fslw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
922           (FSRIW GPR:$rs1, GPR:$rs3, (ImmROTL2RW uimm5:$shamt))>;
923 } // Predicates = [HasStdExtZbt, IsRV64]
924
925 let Predicates = [HasStdExtZbb, IsRV64] in {
926 def : Pat<(add (ctlz (and GPR:$rs1, (i64 0xFFFFFFFF))), (i64 -32)),
927           (CLZW GPR:$rs1)>;
928 // computeKnownBits can't figure out that the and mask on the add result is
929 // unnecessary so we need to pattern match it away.
930 def : Pat<(and (add (ctlz (and GPR:$rs1, (i64 0xFFFFFFFF))), (i64 -32)),
931                (i64 0xFFFFFFFF)),
932           (CLZW GPR:$rs1)>;
933 def : Pat<(cttz (or GPR:$rs1, (i64 0x100000000))),
934           (CTZW GPR:$rs1)>;
935 def : Pat<(ctpop (and GPR:$rs1, (i64 0xFFFFFFFF))), (PCNTW GPR:$rs1)>;
936 } // Predicates = [HasStdExtZbb, IsRV64]
937
938 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
939 def : Pat<(sext_inreg (or (shl GPR:$rs2, (i64 16)),
940                           (and GPR:$rs1, 0x000000000000FFFF)),
941                       i32),
942           (PACKW GPR:$rs1, GPR:$rs2)>;
943 def : Pat<(or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
944               (srl (and GPR:$rs1, 0x00000000FFFF0000),
945                    (i64 16))),
946           (PACKUW GPR:$rs1, GPR:$rs2)>;
947 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]