//===-- RISCVInstrInfoB.td - RISC-V 'B' instructions -------*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file describes the RISC-V instructions from the standard 'B' Bitmanip // extension, version 0.92. // This version is still experimental as the 'B' extension hasn't been // ratified yet. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // Operand definitions. //===----------------------------------------------------------------------===// def UImmLog2XLenHalfAsmOperand : AsmOperandClass { let Name = "UImmLog2XLenHalf"; let RenderMethod = "addImmOperands"; let DiagnosticType = "InvalidUImmLog2XLenHalf"; } def shfl_uimm : Operand, ImmLeafis64Bit()) return isUInt<5>(Imm); return isUInt<4>(Imm); }]> { let ParserMatchClass = UImmLog2XLenHalfAsmOperand; let DecoderMethod = "decodeUImmOperand<5>"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) return false; if (STI.getTargetTriple().isArch64Bit()) return isUInt<5>(Imm); return isUInt<4>(Imm); }]; } //===----------------------------------------------------------------------===// // Instruction class templates //===----------------------------------------------------------------------===// // Some of these templates should be moved to RISCVInstrFormats.td once the B // extension has been ratified. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBUnary funct7, bits<5> funct5, bits<3> funct3, RISCVOpcode opcode, string opcodestr> : RVInstR { let Inst{24-20} = funct5; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBALUW_ri funct3, string opcodestr> : RVInstI; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBShift_ri funct5, bits<3> funct3, RISCVOpcode opcode, string opcodestr> : RVInstI { bits<6> shamt; let Inst{31-27} = funct5; // NOTE: the bit op(26)=1 is used to select funnel shifts. All other // shifts operations and operations that live in the encoding space // of the shifts (single bit operations, grev, gorc) use op(26) = 0 let Inst{26} = 0; let Inst{25-20} = shamt; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBShiftW_ri funct7, bits<3> funct3, RISCVOpcode opcode, string opcodestr> : RVInstI { bits<5> shamt; let Inst{31-25} = funct7; let Inst{24-20} = shamt; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBShfl_ri funct6, bits<3> funct3, RISCVOpcode opcode, string opcodestr> : RVInstI { bits<6> shamt; let Inst{31-26} = funct6; let Inst{25-20} = shamt; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBTernaryR funct2, bits<3> funct3_b, RISCVOpcode opcode, string opcodestr, string argstr> : RVInstR4 { let Inst{14-12} = funct3_b; } // Currently used by FSRI only let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBTernaryImm6 funct3_b, RISCVOpcode opcode, string opcodestr, string argstr> : RVInstR4<0b10, opcode, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt), opcodestr, argstr> { bits<6> shamt; // NOTE: the first argument of RVInstR4 is hardcoded to 0b10 like the other // funnel shift instructions. The second bit of the argument though is // overwritten by the shamt as the encoding of this particular instruction // requires. This is to obtain op(26) = 1 as required by funnel shift // instructions without the need of a confusing argument in the definition // of the instruction. let Inst{25-20} = shamt; let Inst{14-12} = funct3_b; } // Currently used by FSRIW only let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBTernaryImm5 funct2, bits<3> funct3_b, RISCVOpcode opcode, string opcodestr, string argstr> : RVInstR4 { bits<5> shamt; let Inst{24-20} = shamt; let Inst{14-12} = funct3_b; } //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// let Predicates = [HasStdExtZbbOrZbp] in { def ANDN : ALU_rr<0b0100000, 0b111, "andn">, Sched<[]>; def ORN : ALU_rr<0b0100000, 0b110, "orn">, Sched<[]>; def XNOR : ALU_rr<0b0100000, 0b100, "xnor">, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp] let Predicates = [HasStdExtZbb] in { def SLO : ALU_rr<0b0010000, 0b001, "slo">, Sched<[]>; def SRO : ALU_rr<0b0010000, 0b101, "sro">, Sched<[]>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbbOrZbp] in { def ROL : ALU_rr<0b0110000, 0b001, "rol">, Sched<[]>; def ROR : ALU_rr<0b0110000, 0b101, "ror">, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp] let Predicates = [HasStdExtZbs] in { def SBCLR : ALU_rr<0b0100100, 0b001, "sbclr">, Sched<[]>; def SBSET : ALU_rr<0b0010100, 0b001, "sbset">, Sched<[]>; def SBINV : ALU_rr<0b0110100, 0b001, "sbinv">, Sched<[]>; def SBEXT : ALU_rr<0b0100100, 0b101, "sbext">, Sched<[]>; } // Predicates = [HasStdExtZbs] let Predicates = [HasStdExtZbp] in { def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>; def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>; } // Predicates = [HasStdExtZbp] let Predicates = [HasStdExtZbb] in { def SLOI : RVBShift_ri<0b00100, 0b001, OPC_OP_IMM, "sloi">, Sched<[]>; def SROI : RVBShift_ri<0b00100, 0b101, OPC_OP_IMM, "sroi">, Sched<[]>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbbOrZbp] in def RORI : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">, Sched<[]>; let Predicates = [HasStdExtZbs] in { def SBCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "sbclri">, Sched<[]>; def SBSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "sbseti">, Sched<[]>; def SBINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "sbinvi">, Sched<[]>; def SBEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "sbexti">, Sched<[]>; } // Predicates = [HasStdExtZbs] let Predicates = [HasStdExtZbp] in { def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">, Sched<[]>; def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">, Sched<[]>; } // Predicates = [HasStdExtZbp] let Predicates = [HasStdExtZbt] in { def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">, Sched<[]>; def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">, Sched<[]>; def FSL : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">, Sched<[]>; def FSR : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">, Sched<[]>; def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri", "$rd, $rs1, $rs3, $shamt">, Sched<[]>; } // Predicates = [HasStdExtZbt] let Predicates = [HasStdExtZbb] in { def CLZ : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0010011>, "clz">, Sched<[]>; def CTZ : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0010011>, "ctz">, Sched<[]>; def PCNT : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0010011>, "pcnt">, Sched<[]>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbm, IsRV64] in def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, RISCVOpcode<0b0010011>, "bmatflip">, Sched<[]>; let Predicates = [HasStdExtZbb] in { def SEXTB : RVBUnary<0b0110000, 0b00100, 0b001, RISCVOpcode<0b0010011>, "sext.b">, Sched<[]>; def SEXTH : RVBUnary<0b0110000, 0b00101, 0b001, RISCVOpcode<0b0010011>, "sext.h">, Sched<[]>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbr] in { def CRC32B : RVBUnary<0b0110000, 0b10000, 0b001, RISCVOpcode<0b0010011>, "crc32.b">, Sched<[]>; def CRC32H : RVBUnary<0b0110000, 0b10001, 0b001, RISCVOpcode<0b0010011>, "crc32.h">, Sched<[]>; def CRC32W : RVBUnary<0b0110000, 0b10010, 0b001, RISCVOpcode<0b0010011>, "crc32.w">, Sched<[]>; } // Predicates = [HasStdExtZbr] let Predicates = [HasStdExtZbr, IsRV64] in def CRC32D : RVBUnary<0b0110000, 0b10011, 0b001, RISCVOpcode<0b0010011>, "crc32.d">, Sched<[]>; let Predicates = [HasStdExtZbr] in { def CRC32CB : RVBUnary<0b0110000, 0b11000, 0b001, RISCVOpcode<0b0010011>, "crc32c.b">, Sched<[]>; def CRC32CH : RVBUnary<0b0110000, 0b11001, 0b001, RISCVOpcode<0b0010011>, "crc32c.h">, Sched<[]>; def CRC32CW : RVBUnary<0b0110000, 0b11010, 0b001, RISCVOpcode<0b0010011>, "crc32c.w">, Sched<[]>; } // Predicates = [HasStdExtZbr] let Predicates = [HasStdExtZbr, IsRV64] in def CRC32CD : RVBUnary<0b0110000, 0b11011, 0b001, RISCVOpcode<0b0010011>, "crc32c.d">, Sched<[]>; let Predicates = [HasStdExtZbc] in { def CLMUL : ALU_rr<0b0000101, 0b001, "clmul">, Sched<[]>; def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">, Sched<[]>; def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh">, Sched<[]>; } // Predicates = [HasStdExtZbc] let Predicates = [HasStdExtZbb] in { def MIN : ALU_rr<0b0000101, 0b100, "min">, Sched<[]>; def MAX : ALU_rr<0b0000101, 0b101, "max">, Sched<[]>; def MINU : ALU_rr<0b0000101, 0b110, "minu">, Sched<[]>; def MAXU : ALU_rr<0b0000101, 0b111, "maxu">, Sched<[]>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbp] in { def SHFL : ALU_rr<0b0000100, 0b001, "shfl">, Sched<[]>; def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">, Sched<[]>; } // Predicates = [HasStdExtZbp] let Predicates = [HasStdExtZbe] in { def BDEP : ALU_rr<0b0100100, 0b110, "bdep">, Sched<[]>; def BEXT : ALU_rr<0b0000100, 0b110, "bext">, Sched<[]>; } // Predicates = [HasStdExtZbe] let Predicates = [HasStdExtZbbOrZbp] in { def PACK : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>; def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp] let Predicates = [HasStdExtZbm, IsRV64] in { def BMATOR : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>; def BMATXOR : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>; } // Predicates = [HasStdExtZbm, IsRV64] let Predicates = [HasStdExtZbbOrZbp] in def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>; let Predicates = [HasStdExtZbf] in def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>; let Predicates = [HasStdExtZbp] in { def SHFLI : RVBShfl_ri<0b000010, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>; def UNSHFLI : RVBShfl_ri<0b000010, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>; } // Predicates = [HasStdExtZbp] let Predicates = [HasStdExtZbb, IsRV64] in { def ADDIWU : RVBALUW_ri<0b100, "addiwu">, Sched<[]>; def SLLIUW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slliu.w">, Sched<[]>; def ADDWU : ALUW_rr<0b0000101, 0b000, "addwu">, Sched<[]>; def SUBWU : ALUW_rr<0b0100101, 0b000, "subwu">, Sched<[]>; def ADDUW : ALUW_rr<0b0000100, 0b000, "addu.w">, Sched<[]>; def SUBUW : ALUW_rr<0b0100100, 0b000, "subu.w">, Sched<[]>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbb, IsRV64] in { def SLOW : ALUW_rr<0b0010000, 0b001, "slow">, Sched<[]>; def SROW : ALUW_rr<0b0010000, 0b101, "srow">, Sched<[]>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { def ROLW : ALUW_rr<0b0110000, 0b001, "rolw">, Sched<[]>; def RORW : ALUW_rr<0b0110000, 0b101, "rorw">, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp, IsRV64] let Predicates = [HasStdExtZbs, IsRV64] in { def SBCLRW : ALUW_rr<0b0100100, 0b001, "sbclrw">, Sched<[]>; def SBSETW : ALUW_rr<0b0010100, 0b001, "sbsetw">, Sched<[]>; def SBINVW : ALUW_rr<0b0110100, 0b001, "sbinvw">, Sched<[]>; def SBEXTW : ALUW_rr<0b0100100, 0b101, "sbextw">, Sched<[]>; } // Predicates = [HasStdExtZbs, IsRV64] let Predicates = [HasStdExtZbp, IsRV64] in { def GORCW : ALUW_rr<0b0010100, 0b101, "gorcw">, Sched<[]>; def GREVW : ALUW_rr<0b0110100, 0b101, "grevw">, Sched<[]>; } // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbb, IsRV64] in { def SLOIW : RVBShiftW_ri<0b0010000, 0b001, OPC_OP_IMM_32, "sloiw">, Sched<[]>; def SROIW : RVBShiftW_ri<0b0010000, 0b101, OPC_OP_IMM_32, "sroiw">, Sched<[]>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbbOrZbp, IsRV64] in def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">, Sched<[]>; let Predicates = [HasStdExtZbs, IsRV64] in { def SBCLRIW : RVBShiftW_ri<0b0100100, 0b001, OPC_OP_IMM_32, "sbclriw">, Sched<[]>; def SBSETIW : RVBShiftW_ri<0b0010100, 0b001, OPC_OP_IMM_32, "sbsetiw">, Sched<[]>; def SBINVIW : RVBShiftW_ri<0b0110100, 0b001, OPC_OP_IMM_32, "sbinviw">, Sched<[]>; } // Predicates = [HasStdExtZbs, IsRV64] let Predicates = [HasStdExtZbp, IsRV64] in { def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">, Sched<[]>; def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">, Sched<[]>; } // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbt, IsRV64] in { def FSLW : RVBTernaryR<0b10, 0b001, OPC_OP_32, "fslw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>; def FSRW : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>; def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32, "fsriw", "$rd, $rs1, $rs3, $shamt">, Sched<[]>; } // Predicates = [HasStdExtZbt, IsRV64] let Predicates = [HasStdExtZbb, IsRV64] in { def CLZW : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0011011>, "clzw">, Sched<[]>; def CTZW : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0011011>, "ctzw">, Sched<[]>; def PCNTW : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0011011>, "pcntw">, Sched<[]>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbc, IsRV64] in { def CLMULW : ALUW_rr<0b0000101, 0b001, "clmulw">, Sched<[]>; def CLMULRW : ALUW_rr<0b0000101, 0b010, "clmulrw">, Sched<[]>; def CLMULHW : ALUW_rr<0b0000101, 0b011, "clmulhw">, Sched<[]>; } // Predicates = [HasStdExtZbc, IsRV64] let Predicates = [HasStdExtZbp, IsRV64] in { def SHFLW : ALUW_rr<0b0000100, 0b001, "shflw">, Sched<[]>; def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">, Sched<[]>; } // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbe, IsRV64] in { def BDEPW : ALUW_rr<0b0100100, 0b110, "bdepw">, Sched<[]>; def BEXTW : ALUW_rr<0b0000100, 0b110, "bextw">, Sched<[]>; } // Predicates = [HasStdExtZbe, IsRV64] let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { def PACKW : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>; def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp, IsRV64] let Predicates = [HasStdExtZbf, IsRV64] in def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>; //===----------------------------------------------------------------------===// // Future compressed instructions //===----------------------------------------------------------------------===// // The presence of these instructions in the B extension is purely experimental // and they should be moved to the C extension as soon as they are ratified. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVBInstC funct2, string opcodestr> : RVInst16<(outs GPRC:$rs_wb), (ins GPRC:$rs), opcodestr, "$rs", [], InstFormatCR> { bits<3> rs; let Constraints = "$rs = $rs_wb"; let Inst{15-12} = 0b0110; let Inst{11-10} = funct2; let Inst{9-7} = rs; let Inst{6-0} = 0b0000001; } // The namespace RVBC exists to avoid encoding conflicts with the compressed // instructions c.addi16sp and c.lui already implemented in the C extension. let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC] in { def C_NOT : RVBInstC<0b00, "c.not">, Sched<[]>; def C_NEG : RVBInstC<0b01, "c.neg">, Sched<[]>; } // DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtC] let DecoderNamespace = "RVBC", Predicates = [HasStdExtZbproposedc, HasStdExtZbbOrZbp, HasStdExtC, IsRV64] in def C_ZEXTW : RVBInstC<0b10, "c.zext.w">, Sched<[]>; //===----------------------------------------------------------------------===// // Pseudo Instructions //===----------------------------------------------------------------------===// let Predicates = [HasStdExtZbb, IsRV32] in { def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF)>; def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>; } // Predicates = [HasStdExtZbb, IsRV32] let Predicates = [HasStdExtZbb, IsRV64] in { def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF)>; def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>; def : InstAlias<"zext.w $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbbOrZbp] in { def : InstAlias<"rev.p $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00001)>, Sched<[]>; def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>, Sched<[]>; def : InstAlias<"rev.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00011)>, Sched<[]>; def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>, Sched<[]>; def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>, Sched<[]>; def : InstAlias<"rev.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00111)>, Sched<[]>; def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>, Sched<[]>; def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>, Sched<[]>; def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>, Sched<[]>; def : InstAlias<"rev.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01111)>, Sched<[]>; def : InstAlias<"zip.n $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0001)>, Sched<[]>; def : InstAlias<"unzip.n $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>, Sched<[]>; def : InstAlias<"zip2.b $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0010)>, Sched<[]>; def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>, Sched<[]>; def : InstAlias<"zip.b $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0011)>, Sched<[]>; def : InstAlias<"unzip.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>, Sched<[]>; def : InstAlias<"zip4.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0100)>, Sched<[]>; def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>, Sched<[]>; def : InstAlias<"zip2.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0110)>, Sched<[]>; def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>, Sched<[]>; def : InstAlias<"zip.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0111)>, Sched<[]>; def : InstAlias<"unzip.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>, Sched<[]>; def : InstAlias<"orc.p $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00001)>, Sched<[]>; def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>, Sched<[]>; def : InstAlias<"orc.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00011)>, Sched<[]>; def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>, Sched<[]>; def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>, Sched<[]>; def : InstAlias<"orc.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00111)>, Sched<[]>; def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>, Sched<[]>; def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>, Sched<[]>; def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>, Sched<[]>; def : InstAlias<"orc.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01111)>, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp] let Predicates = [HasStdExtZbbOrZbp, IsRV32] in { def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>, Sched<[]>; def : InstAlias<"rev8 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11000)>, Sched<[]>; def : InstAlias<"rev4 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11100)>, Sched<[]>; def : InstAlias<"rev2 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11110)>, Sched<[]>; def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11111)>, Sched<[]>; def : InstAlias<"zip8 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1000)>, Sched<[]>; def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>, Sched<[]>; def : InstAlias<"zip4 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1100)>, Sched<[]>; def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>, Sched<[]>; def : InstAlias<"zip2 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1110)>, Sched<[]>; def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>, Sched<[]>; def : InstAlias<"zip $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1111)>, Sched<[]>; def : InstAlias<"unzip $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1111)>, Sched<[]>; def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>, Sched<[]>; def : InstAlias<"orc8 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11000)>, Sched<[]>; def : InstAlias<"orc4 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11100)>, Sched<[]>; def : InstAlias<"orc2 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11110)>, Sched<[]>; def : InstAlias<"orc $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11111)>, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp, IsRV32] let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>, Sched<[]>; def : InstAlias<"rev8.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011000)>, Sched<[]>; def : InstAlias<"rev4.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011100)>, Sched<[]>; def : InstAlias<"rev2.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011110)>, Sched<[]>; def : InstAlias<"rev.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011111)>, Sched<[]>; def : InstAlias<"rev32 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b100000)>, Sched<[]>; def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b110000)>, Sched<[]>; def : InstAlias<"rev8 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111000)>, Sched<[]>; def : InstAlias<"rev4 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111100)>, Sched<[]>; def : InstAlias<"rev2 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111110)>, Sched<[]>; def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111111)>, Sched<[]>; def : InstAlias<"zip8.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01000)>, Sched<[]>; def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>, Sched<[]>; def : InstAlias<"zip4.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01100)>, Sched<[]>; def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>, Sched<[]>; def : InstAlias<"zip2.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01110)>, Sched<[]>; def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>, Sched<[]>; def : InstAlias<"zip.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01111)>, Sched<[]>; def : InstAlias<"unzip.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>, Sched<[]>; def : InstAlias<"zip16 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b10000)>, Sched<[]>; def : InstAlias<"unzip16 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>, Sched<[]>; def : InstAlias<"zip8 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11000)>, Sched<[]>; def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>, Sched<[]>; def : InstAlias<"zip4 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11100)>, Sched<[]>; def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>, Sched<[]>; def : InstAlias<"zip2 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11110)>, Sched<[]>; def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>, Sched<[]>; def : InstAlias<"zip $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11111)>, Sched<[]>; def : InstAlias<"unzip $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>, Sched<[]>; def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>, Sched<[]>; def : InstAlias<"orc8.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011000)>, Sched<[]>; def : InstAlias<"orc4.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011100)>, Sched<[]>; def : InstAlias<"orc2.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011110)>, Sched<[]>; def : InstAlias<"orc.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011111)>, Sched<[]>; def : InstAlias<"orc32 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b100000)>, Sched<[]>; def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b110000)>, Sched<[]>; def : InstAlias<"orc8 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111000)>, Sched<[]>; def : InstAlias<"orc4 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111100)>, Sched<[]>; def : InstAlias<"orc2 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111110)>, Sched<[]>; def : InstAlias<"orc $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111111)>, Sched<[]>; } // Predicates = [HasStdExtZbbOrZbp, IsRV64] //===----------------------------------------------------------------------===// // Compressed Instruction patterns //===----------------------------------------------------------------------===// let Predicates = [HasStdExtZbproposedc, HasStdExtC] in { def : CompressPat<(XORI GPRC:$rs1, GPRC:$rs1, -1), (C_NOT GPRC:$rs1)>; def : CompressPat<(SUB GPRC:$rs1, X0, GPRC:$rs1), (C_NEG GPRC:$rs1)>; } // Predicates = [HasStdExtZbproposedc, HasStdExtC] let Predicates = [HasStdExtZbproposedc, HasStdExtZbbOrZbp, HasStdExtC, IsRV64] in { def : CompressPat<(PACK GPRC:$rs1, GPRC:$rs1, X0), (C_ZEXTW GPRC:$rs1)>; } // Predicates = [HasStdExtZbproposedc, HasStdExtC, IsRV64] //===----------------------------------------------------------------------===// // Codegen patterns //===----------------------------------------------------------------------===// def SLOIPat : ComplexPattern; def SROIPat : ComplexPattern; def RORIPat : ComplexPattern; def SLLIUWPat : ComplexPattern; def SLOIWPat : ComplexPattern; def SROIWPat : ComplexPattern; def RORIWPat : ComplexPattern; def FSRIWPat : ComplexPattern; let Predicates = [HasStdExtZbbOrZbp] in { def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>; def : Pat<(or GPR:$rs1, (not GPR:$rs2)), (ORN GPR:$rs1, GPR:$rs2)>; def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbbOrZbp] let Predicates = [HasStdExtZbb] in { def : Pat<(xor (shl (xor GPR:$rs1, -1), GPR:$rs2), -1), (SLO GPR:$rs1, GPR:$rs2)>; def : Pat<(xor (srl (xor GPR:$rs1, -1), GPR:$rs2), -1), (SRO GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbbOrZbp] in { def : Pat<(rotl GPR:$rs1, GPR:$rs2), (ROL GPR:$rs1, GPR:$rs2)>; def : Pat<(fshl GPR:$rs1, GPR:$rs1, GPR:$rs2), (ROL GPR:$rs1, GPR:$rs2)>; def : Pat<(rotr GPR:$rs1, GPR:$rs2), (ROR GPR:$rs1, GPR:$rs2)>; def : Pat<(fshr GPR:$rs1, GPR:$rs1, GPR:$rs2), (ROR GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbbOrZbp] let Predicates = [HasStdExtZbs, IsRV32] in def : Pat<(and (xor (shl 1, (and GPR:$rs2, 31)), -1), GPR:$rs1), (SBCLR GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs, IsRV64] in def : Pat<(and (xor (shl 1, (and GPR:$rs2, 63)), -1), GPR:$rs1), (SBCLR GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs] in def : Pat<(and (rotl -2, GPR:$rs2), GPR:$rs1), (SBCLR GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs, IsRV32] in def : Pat<(or (shl 1, (and GPR:$rs2, 31)), GPR:$rs1), (SBSET GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs, IsRV64] in def : Pat<(or (shl 1, (and GPR:$rs2, 63)), GPR:$rs1), (SBSET GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs, IsRV32] in def : Pat<(xor (shl 1, (and GPR:$rs2, 31)), GPR:$rs1), (SBINV GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs, IsRV64] in def : Pat<(xor (shl 1, (and GPR:$rs2, 63)), GPR:$rs1), (SBINV GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs, IsRV32] in def : Pat<(and (srl GPR:$rs1, (and GPR:$rs2, 31)), 1), (SBEXT GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbs, IsRV64] in def : Pat<(and (srl GPR:$rs1, (and GPR:$rs2, 63)), 1), (SBEXT GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbb] in { def : Pat<(SLOIPat GPR:$rs1, uimmlog2xlen:$shamt), (SLOI GPR:$rs1, uimmlog2xlen:$shamt)>; def : Pat<(SROIPat GPR:$rs1, uimmlog2xlen:$shamt), (SROI GPR:$rs1, uimmlog2xlen:$shamt)>; } // Predicates = [HasStdExtZbb] // There's no encoding for roli in the current version of the 'B' extension // (v0.92) as it can be implemented with rori by negating the immediate. // For this reason we pattern-match only against rori[w]. let Predicates = [HasStdExtZbbOrZbp] in def : Pat<(RORIPat GPR:$rs1, uimmlog2xlen:$shamt), (RORI GPR:$rs1, uimmlog2xlen:$shamt)>; // We don't pattern-match sbclri[w], sbseti[w], sbinvi[w] because they are // pattern-matched by simple andi, ori, and xori. let Predicates = [HasStdExtZbs] in def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)), (SBEXTI GPR:$rs1, uimmlog2xlen:$shamt)>; let Predicates = [HasStdExtZbp, IsRV32] in { def : Pat<(or (or (and (srl GPR:$rs1, (i32 1)), (i32 0x55555555)), GPR:$rs1), (and (shl GPR:$rs1, (i32 1)), (i32 0xAAAAAAAA))), (GORCI GPR:$rs1, (i32 1))>; def : Pat<(or (or (and (srl GPR:$rs1, (i32 2)), (i32 0x33333333)), GPR:$rs1), (and (shl GPR:$rs1, (i32 2)), (i32 0xCCCCCCCC))), (GORCI GPR:$rs1, (i32 2))>; def : Pat<(or (or (and (srl GPR:$rs1, (i32 4)), (i32 0x0F0F0F0F)), GPR:$rs1), (and (shl GPR:$rs1, (i32 4)), (i32 0xF0F0F0F0))), (GORCI GPR:$rs1, (i32 4))>; def : Pat<(or (or (and (srl GPR:$rs1, (i32 8)), (i32 0x00FF00FF)), GPR:$rs1), (and (shl GPR:$rs1, (i32 8)), (i32 0xFF00FF00))), (GORCI GPR:$rs1, (i32 8))>; def : Pat<(or (or (srl GPR:$rs1, (i32 16)), GPR:$rs1), (shl GPR:$rs1, (i32 16))), (GORCI GPR:$rs1, (i32 16))>; } // Predicates = [HasStdExtZbp, IsRV32] let Predicates = [HasStdExtZbp, IsRV64] in { def : Pat<(or (or (and (srl GPR:$rs1, (i64 1)), (i64 0x5555555555555555)), GPR:$rs1), (and (shl GPR:$rs1, (i64 1)), (i64 0xAAAAAAAAAAAAAAAA))), (GORCI GPR:$rs1, (i64 1))>; def : Pat<(or (or (and (srl GPR:$rs1, (i64 2)), (i64 0x3333333333333333)), GPR:$rs1), (and (shl GPR:$rs1, (i64 2)), (i64 0xCCCCCCCCCCCCCCCC))), (GORCI GPR:$rs1, (i64 2))>; def : Pat<(or (or (and (srl GPR:$rs1, (i64 4)), (i64 0x0F0F0F0F0F0F0F0F)), GPR:$rs1), (and (shl GPR:$rs1, (i64 4)), (i64 0xF0F0F0F0F0F0F0F0))), (GORCI GPR:$rs1, (i64 4))>; def : Pat<(or (or (and (srl GPR:$rs1, (i64 8)), (i64 0x00FF00FF00FF00FF)), GPR:$rs1), (and (shl GPR:$rs1, (i64 8)), (i64 0xFF00FF00FF00FF00))), (GORCI GPR:$rs1, (i64 8))>; def : Pat<(or (or (and (srl GPR:$rs1, (i64 16)), (i64 0x0000FFFF0000FFFF)), GPR:$rs1), (and (shl GPR:$rs1, (i64 16)), (i64 0xFFFF0000FFFF0000))), (GORCI GPR:$rs1, (i64 16))>; def : Pat<(or (or (srl GPR:$rs1, (i64 32)), GPR:$rs1), (shl GPR:$rs1, (i64 32))), (GORCI GPR:$rs1, (i64 32))>; } // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbp, IsRV32] in { def : Pat<(or (and (shl GPR:$rs1, (i32 1)), (i32 0xAAAAAAAA)), (and (srl GPR:$rs1, (i32 1)), (i32 0x55555555))), (GREVI GPR:$rs1, (i32 1))>; def : Pat<(or (and (shl GPR:$rs1, (i32 2)), (i32 0xCCCCCCCC)), (and (srl GPR:$rs1, (i32 2)), (i32 0x33333333))), (GREVI GPR:$rs1, (i32 2))>; def : Pat<(or (and (shl GPR:$rs1, (i32 4)), (i32 0xF0F0F0F0)), (and (srl GPR:$rs1, (i32 4)), (i32 0x0F0F0F0F))), (GREVI GPR:$rs1, (i32 4))>; def : Pat<(or (and (shl GPR:$rs1, (i32 8)), (i32 0xFF00FF00)), (and (srl GPR:$rs1, (i32 8)), (i32 0x00FF00FF))), (GREVI GPR:$rs1, (i32 8))>; def : Pat<(rotr (bswap GPR:$rs1), (i32 16)), (GREVI GPR:$rs1, (i32 8))>; def : Pat<(or (shl GPR:$rs1, (i32 16)), (srl GPR:$rs1, (i32 16))), (GREVI GPR:$rs1, (i32 16))>; def : Pat<(rotl GPR:$rs1, (i32 16)), (GREVI GPR:$rs1, (i32 16))>; def : Pat<(bswap GPR:$rs1), (GREVI GPR:$rs1, (i32 24))>; def : Pat<(bitreverse GPR:$rs1), (GREVI GPR:$rs1, (i32 31))>; } // Predicates = [HasStdExtZbp, IsRV32] let Predicates = [HasStdExtZbp, IsRV64] in { def : Pat<(or (and (shl GPR:$rs1, (i64 1)), (i64 0xAAAAAAAAAAAAAAAA)), (and (srl GPR:$rs1, (i64 1)), (i64 0x5555555555555555))), (GREVI GPR:$rs1, (i64 1))>; def : Pat<(or (and (shl GPR:$rs1, (i64 2)), (i64 0xCCCCCCCCCCCCCCCC)), (and (srl GPR:$rs1, (i64 2)), (i64 0x3333333333333333))), (GREVI GPR:$rs1, (i64 2))>; def : Pat<(or (and (shl GPR:$rs1, (i64 4)), (i64 0xF0F0F0F0F0F0F0F0)), (and (srl GPR:$rs1, (i64 4)), (i64 0x0F0F0F0F0F0F0F0F))), (GREVI GPR:$rs1, (i64 4))>; def : Pat<(or (and (shl GPR:$rs1, (i64 8)), (i64 0xFF00FF00FF00FF00)), (and (srl GPR:$rs1, (i64 8)), (i64 0x00FF00FF00FF00FF))), (GREVI GPR:$rs1, (i64 8))>; def : Pat<(or (and (shl GPR:$rs1, (i64 16)), (i64 0xFFFF0000FFFF0000)), (and (srl GPR:$rs1, (i64 16)), (i64 0x0000FFFF0000FFFF))), (GREVI GPR:$rs1, (i64 16))>; def : Pat<(or (shl GPR:$rs1, (i64 32)), (srl GPR:$rs1, (i64 32))), (GREVI GPR:$rs1, (i64 32))>; def : Pat<(rotl GPR:$rs1, (i64 32)), (GREVI GPR:$rs1, (i64 32))>; def : Pat<(bswap GPR:$rs1), (GREVI GPR:$rs1, (i64 56))>; def : Pat<(bitreverse GPR:$rs1), (GREVI GPR:$rs1, (i64 63))>; } // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbt] in { def : Pat<(or (and (xor GPR:$rs2, -1), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)), (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>; def : Pat<(riscv_selectcc GPR:$rs2, (XLenVT 0), (XLenVT 17), GPR:$rs3, GPR:$rs1), (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>; def : Pat<(fshl GPR:$rs1, GPR:$rs2, GPR:$rs3), (FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>; def : Pat<(fshr GPR:$rs1, GPR:$rs2, GPR:$rs3), (FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>; def : Pat<(fshr GPR:$rs1, GPR:$rs2, uimmlog2xlen:$shamt), (FSRI GPR:$rs1, GPR:$rs2, uimmlog2xlen:$shamt)>; } // Predicates = [HasStdExtZbt] let Predicates = [HasStdExtZbb] in { def : Pat<(ctlz GPR:$rs1), (CLZ GPR:$rs1)>; def : Pat<(cttz GPR:$rs1), (CTZ GPR:$rs1)>; def : Pat<(ctpop GPR:$rs1), (PCNT GPR:$rs1)>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbb, IsRV32] in def : Pat<(sra (shl GPR:$rs1, (i32 24)), (i32 24)), (SEXTB GPR:$rs1)>; let Predicates = [HasStdExtZbb, IsRV64] in def : Pat<(sra (shl GPR:$rs1, (i64 56)), (i64 56)), (SEXTB GPR:$rs1)>; let Predicates = [HasStdExtZbb, IsRV32] in def : Pat<(sra (shl GPR:$rs1, (i32 16)), (i32 16)), (SEXTH GPR:$rs1)>; let Predicates = [HasStdExtZbb, IsRV64] in def : Pat<(sra (shl GPR:$rs1, (i64 48)), (i64 48)), (SEXTH GPR:$rs1)>; let Predicates = [HasStdExtZbb] in { def : Pat<(smin GPR:$rs1, GPR:$rs2), (MIN GPR:$rs1, GPR:$rs2)>; def : Pat<(riscv_selectcc GPR:$rs1, GPR:$rs2, (XLenVT 20), GPR:$rs1, GPR:$rs2), (MIN GPR:$rs1, GPR:$rs2)>; def : Pat<(smax GPR:$rs1, GPR:$rs2), (MAX GPR:$rs1, GPR:$rs2)>; def : Pat<(riscv_selectcc GPR:$rs2, GPR:$rs1, (XLenVT 20), GPR:$rs1, GPR:$rs2), (MAX GPR:$rs1, GPR:$rs2)>; def : Pat<(umin GPR:$rs1, GPR:$rs2), (MINU GPR:$rs1, GPR:$rs2)>; def : Pat<(riscv_selectcc GPR:$rs1, GPR:$rs2, (XLenVT 12), GPR:$rs1, GPR:$rs2), (MINU GPR:$rs1, GPR:$rs2)>; def : Pat<(umax GPR:$rs1, GPR:$rs2), (MAXU GPR:$rs1, GPR:$rs2)>; def : Pat<(riscv_selectcc GPR:$rs2, GPR:$rs1, (XLenVT 12), GPR:$rs1, GPR:$rs2), (MAXU GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbb] let Predicates = [HasStdExtZbbOrZbp, IsRV32] in def : Pat<(or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16))), (PACK GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbbOrZbp, IsRV64] in def : Pat<(or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32))), (PACK GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbbOrZbp, IsRV32] in def : Pat<(or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16))), (PACKU GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbbOrZbp, IsRV64] in def : Pat<(or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32))), (PACKU GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbbOrZbp] in def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFF00), (and GPR:$rs1, 0x00FF)), (PACKH GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbp, IsRV32] in { def : Pat<(or (or (and (shl GPR:$rs1, (i32 8)), (i32 0x00FF0000)), (and GPR:$rs1, (i32 0xFF0000FF))), (and (srl GPR:$rs1, (i32 8)), (i32 0x0000FF00))), (SHFLI GPR:$rs1, (i32 8))>; def : Pat<(or (or (and (shl GPR:$rs1, (i32 4)), (i32 0x0F000F00)), (and GPR:$rs1, (i32 0xF00FF00F))), (and (srl GPR:$rs1, (i32 4)), (i32 0x00F000F0))), (SHFLI GPR:$rs1, (i32 4))>; def : Pat<(or (or (and (shl GPR:$rs1, (i32 2)), (i32 0x30303030)), (and GPR:$rs1, (i32 0xC3C3C3C3))), (and (srl GPR:$rs1, (i32 2)), (i32 0x0C0C0C0C))), (SHFLI GPR:$rs1, (i32 2))>; def : Pat<(or (or (and (shl GPR:$rs1, (i32 1)), (i32 0x44444444)), (and GPR:$rs1, (i32 0x99999999))), (and (srl GPR:$rs1, (i32 1)), (i32 0x22222222))), (SHFLI GPR:$rs1, (i32 1))>; } // Predicates = [HasStdExtZbp, IsRV32] let Predicates = [HasStdExtZbp, IsRV64] in { def : Pat<(or (or (and (shl GPR:$rs1, (i64 16)), (i64 0x0000FFFF00000000)), (and GPR:$rs1, (i64 0xFFFF00000000FFFF))), (and (srl GPR:$rs1, (i64 16)), (i64 0x00000000FFFF0000))), (SHFLI GPR:$rs1, (i64 16))>; def : Pat<(or (or (and (shl GPR:$rs1, (i64 8)), (i64 0x00FF000000FF0000)), (and GPR:$rs1, (i64 0xFF0000FFFF0000FF))), (and (srl GPR:$rs1, (i64 8)), (i64 0x0000FF000000FF00))), (SHFLI GPR:$rs1, (i64 8))>; def : Pat<(or (or (and (shl GPR:$rs1, (i64 4)), (i64 0x0F000F000F000F00)), (and GPR:$rs1, (i64 0xF00FF00FF00FF00F))), (and (srl GPR:$rs1, (i64 4)), (i64 0x00F000F000F000F0))), (SHFLI GPR:$rs1, (i64 4))>; def : Pat<(or (or (and (shl GPR:$rs1, (i64 2)), (i64 0x3030303030303030)), (and GPR:$rs1, (i64 0xC3C3C3C3C3C3C3C3))), (and (srl GPR:$rs1, (i64 2)), (i64 0x0C0C0C0C0C0C0C0C))), (SHFLI GPR:$rs1, (i64 2))>; def : Pat<(or (or (and (shl GPR:$rs1, (i64 1)), (i64 0x4444444444444444)), (and GPR:$rs1, (i64 0x9999999999999999))), (and (srl GPR:$rs1, (i64 1)), (i64 0x2222222222222222))), (SHFLI GPR:$rs1, (i64 1))>; } // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbb, IsRV64] in { def : Pat<(and (add GPR:$rs, simm12:$simm12), (i64 0xFFFFFFFF)), (ADDIWU GPR:$rs, simm12:$simm12)>; def : Pat<(SLLIUWPat GPR:$rs1, uimmlog2xlen:$shamt), (SLLIUW GPR:$rs1, uimmlog2xlen:$shamt)>; def : Pat<(and (add GPR:$rs1, GPR:$rs2), (i64 0xFFFFFFFF)), (ADDWU GPR:$rs1, GPR:$rs2)>; def : Pat<(and (sub GPR:$rs1, GPR:$rs2), (i64 0xFFFFFFFF)), (SUBWU GPR:$rs1, GPR:$rs2)>; def : Pat<(add GPR:$rs1, (and GPR:$rs2, (i64 0xFFFFFFFF))), (ADDUW GPR:$rs1, GPR:$rs2)>; def : Pat<(sub GPR:$rs1, (and GPR:$rs2, (i64 0xFFFFFFFF))), (SUBUW GPR:$rs1, GPR:$rs2)>; def : Pat<(xor (riscv_sllw (xor GPR:$rs1, -1), GPR:$rs2), -1), (SLOW GPR:$rs1, GPR:$rs2)>; def : Pat<(xor (riscv_srlw (xor GPR:$rs1, -1), GPR:$rs2), -1), (SROW GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { def : Pat<(or (riscv_sllw (assertsexti32 GPR:$rs1), (assertsexti32 GPR:$rs2)), (riscv_srlw (assertsexti32 GPR:$rs1), (sub (i64 0), (assertsexti32 GPR:$rs2)))), (ROLW GPR:$rs1, GPR:$rs2)>; def : Pat<(or (riscv_sllw (assertsexti32 GPR:$rs1), (sub (i64 0), (assertsexti32 GPR:$rs2))), (riscv_srlw (assertsexti32 GPR:$rs1), (assertsexti32 GPR:$rs2))), (RORW GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbbOrZbp, IsRV64] let Predicates = [HasStdExtZbs, IsRV64] in { def : Pat<(and (xor (riscv_sllw 1, (assertsexti32 GPR:$rs2)), -1), (assertsexti32 GPR:$rs1)), (SBCLRW GPR:$rs1, GPR:$rs2)>; def : Pat<(or (riscv_sllw 1, (assertsexti32 GPR:$rs2)), (assertsexti32 GPR:$rs1)), (SBSETW GPR:$rs1, GPR:$rs2)>; def : Pat<(xor (riscv_sllw 1, (assertsexti32 GPR:$rs2)), (assertsexti32 GPR:$rs1)), (SBINVW GPR:$rs1, GPR:$rs2)>; def : Pat<(and (riscv_srlw (assertsexti32 GPR:$rs1), (assertsexti32 GPR:$rs2)), 1), (SBEXTW GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbs, IsRV64] let Predicates = [HasStdExtZbb, IsRV64] in { def : Pat<(SLOIWPat GPR:$rs1, uimmlog2xlen:$shamt), (SLOIW GPR:$rs1, uimmlog2xlen:$shamt)>; def : Pat<(SROIWPat GPR:$rs1, uimmlog2xlen:$shamt), (SROIW GPR:$rs1, uimmlog2xlen:$shamt)>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbbOrZbp, IsRV64] in def : Pat<(RORIWPat GPR:$rs1, uimmlog2xlen:$shamt), (RORIW GPR:$rs1, uimmlog2xlen:$shamt)>; let Predicates = [HasStdExtZbp, IsRV64] in { def : Pat<(sext_inreg (or (or (and (srl GPR:$rs1, (i64 1)), (i64 0x55555555)), GPR:$rs1), (and (shl GPR:$rs1, (i64 1)), (i64 0xAAAAAAAA))), i32), (GORCIW GPR:$rs1, (i64 1))>; def : Pat<(sext_inreg (or (or (and (srl GPR:$rs1, (i64 2)), (i64 0x33333333)), GPR:$rs1), (and (shl GPR:$rs1, (i64 2)), (i64 0xCCCCCCCC))), i32), (GORCIW GPR:$rs1, (i64 2))>; def : Pat<(sext_inreg (or (or (and (srl GPR:$rs1, (i64 4)), (i64 0x0F0F0F0F)), GPR:$rs1), (and (shl GPR:$rs1, (i64 4)), (i64 0xF0F0F0F0))), i32), (GORCIW GPR:$rs1, (i64 4))>; def : Pat<(sext_inreg (or (or (and (srl GPR:$rs1, (i64 8)), (i64 0x00FF00FF)), GPR:$rs1), (and (shl GPR:$rs1, (i64 8)), (i64 0xFF00FF00))), i32), (GORCIW GPR:$rs1, (i64 8))>; def : Pat<(sext_inreg (or (or (and (srl GPR:$rs1, (i64 16)), (i64 0x0000FFFF)), GPR:$rs1), (and (shl GPR:$rs1, (i64 16)), (i64 0xFFFF0000))), i32), (GORCIW GPR:$rs1, (i64 16))>; def : Pat<(sext_inreg (or (or (srl (and GPR:$rs1, (i64 0xFFFF0000)), (i64 16)), GPR:$rs1), (shl GPR:$rs1, (i64 16))), i32), (GORCIW GPR:$rs1, (i64 16))>; def : Pat<(sext_inreg (or (and (shl GPR:$rs1, (i64 1)), (i64 0xAAAAAAAA)), (and (srl GPR:$rs1, (i64 1)), (i64 0x55555555))), i32), (GREVIW GPR:$rs1, (i64 1))>; def : Pat<(sext_inreg (or (and (shl GPR:$rs1, (i64 2)), (i64 0xCCCCCCCC)), (and (srl GPR:$rs1, (i64 2)), (i64 0x33333333))), i32), (GREVIW GPR:$rs1, (i64 2))>; def : Pat<(sext_inreg (or (and (shl GPR:$rs1, (i64 4)), (i64 0xF0F0F0F0)), (and (srl GPR:$rs1, (i64 4)), (i64 0x0F0F0F0F))), i32), (GREVIW GPR:$rs1, (i64 4))>; def : Pat<(sext_inreg (or (and (shl GPR:$rs1, (i64 8)), (i64 0xFF00FF00)), (and (srl GPR:$rs1, (i64 8)), (i64 0x00FF00FF))), i32), (GREVIW GPR:$rs1, (i64 8))>; def : Pat<(sext_inreg (or (shl GPR:$rs1, (i64 16)), (srl (and GPR:$rs1, 0xFFFF0000), (i64 16))), i32), (GREVIW GPR:$rs1, (i64 16))>; def : Pat<(sra (bswap GPR:$rs1), (i64 32)), (GREVIW GPR:$rs1, (i64 24))>; def : Pat<(sra (bitreverse GPR:$rs1), (i64 32)), (GREVIW GPR:$rs1, (i64 31))>; } // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbt, IsRV64] in { def : Pat<(riscv_selectcc (and (assertsexti32 GPR:$rs3), 31), (i64 0), (i64 17), (assertsexti32 GPR:$rs1), (or (riscv_sllw (assertsexti32 GPR:$rs1), (and (assertsexti32 GPR:$rs3), 31)), (riscv_srlw (assertsexti32 GPR:$rs2), (sub (i64 32), (assertsexti32 GPR:$rs3))))), (FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>; def : Pat<(riscv_selectcc (and (assertsexti32 GPR:$rs3), 31), (i64 0), (i64 17), (assertsexti32 GPR:$rs2), (or (riscv_sllw (assertsexti32 GPR:$rs1), (sub (i64 32), (assertsexti32 GPR:$rs3))), (riscv_srlw (assertsexti32 GPR:$rs2), (and (assertsexti32 GPR:$rs3), 31)))), (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>; def : Pat<(FSRIWPat GPR:$rs1, GPR:$rs2, uimmlog2xlen:$shamt), (FSRIW GPR:$rs1, GPR:$rs2, uimmlog2xlen:$shamt)>; } // Predicates = [HasStdExtZbt, IsRV64] let Predicates = [HasStdExtZbb, IsRV64] in { def : Pat<(add (ctlz (and GPR:$rs1, (i64 0xFFFFFFFF))), (i64 -32)), (CLZW GPR:$rs1)>; // We don't pattern-match CTZW here as it has the same pattern and result as // RV64 CTZ def : Pat<(ctpop (and GPR:$rs1, (i64 0xFFFFFFFF))), (PCNTW GPR:$rs1)>; } // Predicates = [HasStdExtZbb, IsRV64] let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { def : Pat<(sext_inreg (or (shl (assertsexti32 GPR:$rs2), (i64 16)), (and (assertsexti32 GPR:$rs1), 0x000000000000FFFF)), i32), (PACKW GPR:$rs1, GPR:$rs2)>; def : Pat<(or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000), (srl (and (assertsexti32 GPR:$rs1), 0x00000000FFFF0000), (i64 16))), (PACKUW GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbbOrZbp, IsRV64]