diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVInstrInfoB.td')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfoB.td | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td new file mode 100644 index 000000000000..34a463626e29 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td @@ -0,0 +1,634 @@ +//===-- 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<XLenVT>, ImmLeaf<XLenVT, [{ + if (Subtarget->is64Bit()) + 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<bits<7> funct7, bits<5> funct5, bits<3> funct3, + RISCVOpcode opcode, string opcodestr> + : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1), + opcodestr, "$rd, $rs1"> { + let Inst{24-20} = funct5; +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVBALUW_ri<bits<3> funct3, string opcodestr> + : RVInstI<funct3, OPC_OP_IMM_32, (outs GPR:$rd), + (ins GPR:$rs1, simm12:$imm12), opcodestr, "$rd, $rs1, $imm12">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVBShift_ri<bits<5> funct5, bits<3> funct3, RISCVOpcode opcode, + string opcodestr> + : RVInstI<funct3, opcode, (outs GPR:$rd), + (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr, + "$rd, $rs1, $shamt"> { + 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<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, + string opcodestr> + : RVInstI<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1, uimm5:$shamt), + opcodestr, "$rd, $rs1, $shamt"> { + bits<5> shamt; + + let Inst{31-25} = funct7; + let Inst{24-20} = shamt; +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVBShfl_ri<bits<6> funct6, bits<3> funct3, RISCVOpcode opcode, + string opcodestr> + : RVInstI<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1, shfl_uimm:$shamt), + opcodestr, "$rd, $rs1, $shamt"> { + bits<6> shamt; + + let Inst{31-26} = funct6; + let Inst{25-20} = shamt; +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVBTernaryR<bits<2> funct2, bits<3> funct3_b, RISCVOpcode opcode, + string opcodestr, string argstr> + : RVInstR4<funct2, opcode, (outs GPR:$rd), + (ins GPR:$rs1, GPR:$rs2, GPR:$rs3), opcodestr, argstr> { + let Inst{14-12} = funct3_b; +} + +// Currently used by FSRI only +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVBTernaryImm6<bits<3> 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<bits<2> funct2, bits<3> funct3_b, RISCVOpcode opcode, + string opcodestr, string argstr> + : RVInstR4<funct2, opcode, (outs GPR:$rd), + (ins GPR:$rs1, GPR:$rs3, uimm5:$shamt), opcodestr, argstr> { + 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<bits<2> 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] |