//===-- RISCVInstrInfoXCV.td - CORE-V 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 vendor extensions defined by Core-V extensions. // //===----------------------------------------------------------------------===// let DecoderNamespace = "XCVbitmanip" in { class CVInstBitManipRII funct2, bits<3> funct3, dag outs, dag ins, string opcodestr, string argstr> : RVInstIBase { bits<5> is3; bits<5> is2; let Inst{31-30} = funct2; let Inst{29-25} = is3; let Inst{24-20} = is2; } class CVBitManipRII funct2, bits<3> funct3, string opcodestr, Operand i3type = uimm5> : CVInstBitManipRII; class CVBitManipRR funct7, string opcodestr> : RVInstR; class CVBitManipR funct7, string opcodestr> : RVInstR { let rs2 = 0b00000; } } let Predicates = [HasVendorXCVbitmanip, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { def CV_EXTRACT : CVBitManipRII<0b00, 0b000, "cv.extract">; def CV_EXTRACTU : CVBitManipRII<0b01, 0b000, "cv.extractu">; def CV_BCLR : CVBitManipRII<0b00, 0b001, "cv.bclr">; def CV_BSET : CVBitManipRII<0b01, 0b001, "cv.bset">; def CV_BITREV : CVBitManipRII<0b11, 0b001, "cv.bitrev", uimm2>; def CV_EXTRACTR : CVBitManipRR<0b0011000, "cv.extractr">; def CV_EXTRACTUR : CVBitManipRR<0b0011001, "cv.extractur">; let Constraints = "$rd = $rd_wb" in { def CV_INSERT : CVInstBitManipRII<0b10, 0b000, (outs GPR:$rd_wb), (ins GPR:$rd, GPR:$rs1, uimm5:$is3, uimm5:$is2), "cv.insert", "$rd, $rs1, $is3, $is2">; def CV_INSERTR : RVInstR<0b0011010, 0b011, OPC_CUSTOM_1, (outs GPR:$rd_wb), (ins GPR:$rd, GPR:$rs1, GPR:$rs2), "cv.insertr", "$rd, $rs1, $rs2">; } def CV_BCLRR : CVBitManipRR<0b0011100, "cv.bclrr">; def CV_BSETR : CVBitManipRR<0b0011101, "cv.bsetr">; def CV_ROR : CVBitManipRR<0b0100000, "cv.ror">; def CV_FF1 : CVBitManipR<0b0100001, "cv.ff1">; def CV_FL1 : CVBitManipR<0b0100010, "cv.fl1">; def CV_CLB : CVBitManipR<0b0100011, "cv.clb">; def CV_CNT : CVBitManipR<0b0100100, "cv.cnt">; } class CVInstMac funct7, bits<3> funct3, string opcodestr> : RVInstR { let DecoderNamespace = "XCVmac"; } class CVInstMacMulN funct2, bits<3> funct3, dag outs, dag ins, string opcodestr> : RVInstRBase { bits<5> imm5; let Inst{31-30} = funct2; let Inst{29-25} = imm5; let DecoderNamespace = "XCVmac"; } class CVInstMacN funct2, bits<3> funct3, string opcodestr> : CVInstMacMulN; class CVInstMulN funct2, bits<3> funct3, string opcodestr> : CVInstMacMulN; let Predicates = [HasVendorXCVmac, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 0, Constraints = "$rd = $rd_wb" in { // 32x32 bit macs def CV_MAC : CVInstMac<0b1001000, 0b011, "cv.mac">, Sched<[]>; def CV_MSU : CVInstMac<0b1001001, 0b011, "cv.msu">, Sched<[]>; // Signed 16x16 bit macs with imm def CV_MACSN : CVInstMacN<0b00, 0b110, "cv.macsn">, Sched<[]>; def CV_MACHHSN : CVInstMacN<0b01, 0b110, "cv.machhsn">, Sched<[]>; def CV_MACSRN : CVInstMacN<0b10, 0b110, "cv.macsrn">, Sched<[]>; def CV_MACHHSRN : CVInstMacN<0b11, 0b110, "cv.machhsrn">, Sched<[]>; // Unsigned 16x16 bit macs with imm def CV_MACUN : CVInstMacN<0b00, 0b111, "cv.macun">, Sched<[]>; def CV_MACHHUN : CVInstMacN<0b01, 0b111, "cv.machhun">, Sched<[]>; def CV_MACURN : CVInstMacN<0b10, 0b111, "cv.macurn">, Sched<[]>; def CV_MACHHURN : CVInstMacN<0b11, 0b111, "cv.machhurn">, Sched<[]>; } // Predicates = [HasVendorXCVmac, IsRV32], hasSideEffects = 0, mayLoad = 0... let Predicates = [HasVendorXCVmac, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { // Signed 16x16 bit muls with imm def CV_MULSN : CVInstMulN<0b00, 0b100, "cv.mulsn">, Sched<[]>; def CV_MULHHSN : CVInstMulN<0b01, 0b100, "cv.mulhhsn">, Sched<[]>; def CV_MULSRN : CVInstMulN<0b10, 0b100, "cv.mulsrn">, Sched<[]>; def CV_MULHHSRN : CVInstMulN<0b11, 0b100, "cv.mulhhsrn">, Sched<[]>; // Unsigned 16x16 bit muls with imm def CV_MULUN : CVInstMulN<0b00, 0b101, "cv.mulun">, Sched<[]>; def CV_MULHHUN : CVInstMulN<0b01, 0b101, "cv.mulhhun">, Sched<[]>; def CV_MULURN : CVInstMulN<0b10, 0b101, "cv.mulurn">, Sched<[]>; def CV_MULHHURN : CVInstMulN<0b11, 0b101, "cv.mulhhurn">, Sched<[]>; } // Predicates = [HasVendorXCVmac, IsRV32], hasSideEffects = 0, mayLoad = 0... let Predicates = [HasVendorXCVmac, IsRV32] in { // Xcvmac Pseudo Instructions // Signed 16x16 bit muls def : InstAlias<"cv.muls $rd1, $rs1, $rs2", (CV_MULSN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>; def : InstAlias<"cv.mulhhs $rd1, $rs1, $rs2", (CV_MULHHSN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>; // Unsigned 16x16 bit muls def : InstAlias<"cv.mulu $rd1, $rs1, $rs2", (CV_MULUN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>; def : InstAlias<"cv.mulhhu $rd1, $rs1, $rs2", (CV_MULHHUN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>; } // Predicates = [HasVendorXCVmac, IsRV32] let DecoderNamespace = "XCValu" in { class CVInstAluRRI funct2, bits<3> funct3, string opcodestr> : RVInstRBase { bits<5> imm5; let Inst{31-30} = funct2; let Inst{29-25} = imm5; } class CVInstAluRR funct7, bits<3> funct3, string opcodestr> : RVInstR; class CVInstAluRRNR funct7, bits<3> funct3, string opcodestr> : RVInstR; class CVInstAluRI funct7, bits<3> funct3, string opcodestr> : RVInstIBase { bits<5> imm5; let Inst{31-25} = funct7; let Inst{24-20} = imm5; } class CVInstAluR funct7, bits<3> funct3, string opcodestr> : RVInstR { let rs2 = 0b00000; } } // DecoderNamespace = "XCValu" let Predicates = [HasVendorXCValu, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { // General ALU Operations def CV_ABS : CVInstAluR<0b0101000, 0b011, "cv.abs">, Sched<[]>; def CV_SLET : CVInstAluRR<0b0101001, 0b011, "cv.slet">, Sched<[]>; def CV_SLETU : CVInstAluRR<0b0101010, 0b011, "cv.sletu">, Sched<[]>; def CV_MIN : CVInstAluRR<0b0101011, 0b011, "cv.min">, Sched<[]>; def CV_MINU : CVInstAluRR<0b0101100, 0b011, "cv.minu">, Sched<[]>; def CV_MAX : CVInstAluRR<0b0101101, 0b011, "cv.max">, Sched<[]>; def CV_MAXU : CVInstAluRR<0b0101110, 0b011, "cv.maxu">, Sched<[]>; def CV_EXTHS : CVInstAluR<0b0110000, 0b011, "cv.exths">, Sched<[]>; def CV_EXTHZ : CVInstAluR<0b0110001, 0b011, "cv.exthz">, Sched<[]>; def CV_EXTBS : CVInstAluR<0b0110010, 0b011, "cv.extbs">, Sched<[]>; def CV_EXTBZ : CVInstAluR<0b0110011, 0b011, "cv.extbz">, Sched<[]>; def CV_CLIP : CVInstAluRI<0b0111000, 0b011, "cv.clip">, Sched<[]>; def CV_CLIPU : CVInstAluRI<0b0111001, 0b011, "cv.clipu">, Sched<[]>; def CV_CLIPR : CVInstAluRR<0b0111010, 0b011, "cv.clipr">, Sched<[]>; def CV_CLIPUR : CVInstAluRR<0b0111011, 0b011, "cv.clipur">, Sched<[]>; def CV_ADDN : CVInstAluRRI<0b00, 0b010, "cv.addn">, Sched<[]>; def CV_ADDUN : CVInstAluRRI<0b01, 0b010, "cv.addun">, Sched<[]>; def CV_ADDRN : CVInstAluRRI<0b10, 0b010, "cv.addrn">, Sched<[]>; def CV_ADDURN : CVInstAluRRI<0b11, 0b010, "cv.addurn">, Sched<[]>; def CV_SUBN : CVInstAluRRI<0b00, 0b011, "cv.subn">, Sched<[]>; def CV_SUBUN : CVInstAluRRI<0b01, 0b011, "cv.subun">, Sched<[]>; def CV_SUBRN : CVInstAluRRI<0b10, 0b011, "cv.subrn">, Sched<[]>; def CV_SUBURN : CVInstAluRRI<0b11, 0b011, "cv.suburn">, Sched<[]>; } // Predicates = [HasVendorXCValu, IsRV32], // hasSideEffects = 0, mayLoad = 0, mayStore = 0 let Predicates = [HasVendorXCValu, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 0, Constraints = "$rd = $rd_wb" in { def CV_ADDNR : CVInstAluRRNR<0b1000000, 0b011, "cv.addnr">, Sched<[]>; def CV_ADDUNR : CVInstAluRRNR<0b1000001, 0b011, "cv.addunr">, Sched<[]>; def CV_ADDRNR : CVInstAluRRNR<0b1000010, 0b011, "cv.addrnr">, Sched<[]>; def CV_ADDURNR : CVInstAluRRNR<0b1000011, 0b011, "cv.addurnr">, Sched<[]>; def CV_SUBNR : CVInstAluRRNR<0b1000100, 0b011, "cv.subnr">, Sched<[]>; def CV_SUBUNR : CVInstAluRRNR<0b1000101, 0b011, "cv.subunr">, Sched<[]>; def CV_SUBRNR : CVInstAluRRNR<0b1000110, 0b011, "cv.subrnr">, Sched<[]>; def CV_SUBURNR : CVInstAluRRNR<0b1000111, 0b011, "cv.suburnr">, Sched<[]>; } // Predicates = [HasVendorXCValu, IsRV32], // hasSideEffects = 0, mayLoad = 0, mayStore = 0, // Constraints = "$rd = $rd_wb" class CVInstSIMDRR funct5, bit F, bit funct1, bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInstRBase { let Inst{31-27} = funct5; let Inst{26} = F; let Inst{25} = funct1; let DecoderNamespace = "XCVsimd"; } class CVInstSIMDRI funct5, bit F, bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInstIBase { bits<6> imm6; let Inst{31-27} = funct5; let Inst{26} = F; let Inst{25} = imm6{0}; // funct1 unused let Inst{24-20} = imm6{5-1}; let DecoderNamespace = "XCVsimd"; } class CVSIMDRR funct5, bit F, bit funct1, bits<3> funct3, string opcodestr> : CVInstSIMDRR; class CVSIMDRRWb funct5, bit F, bit funct1, bits<3> funct3, string opcodestr> : CVInstSIMDRR { let Constraints = "$rd = $rd_wb"; } class CVSIMDRI funct5, bit F, bits<3> funct3, string opcodestr> : CVInstSIMDRI; class CVSIMDRIWb funct5, bit F, bits<3> funct3, string opcodestr> : CVInstSIMDRI { let Constraints = "$rd = $rd_wb"; } class CVSIMDRU funct5, bit F, bits<3> funct3, string opcodestr, Operand immtype = uimm6> : CVInstSIMDRI; class CVSIMDRUWb funct5, bit F, bits<3> funct3, string opcodestr> : CVInstSIMDRI { let Constraints = "$rd = $rd_wb"; } class CVSIMDR funct5, bit F, bit funct1, bits<3> funct3, string opcodestr> : CVInstSIMDRR { let rs2 = 0b00000; } multiclass CVSIMDBinarySigned funct5, bit F, bit funct1, string mnemonic> { def CV_ # NAME # _H : CVSIMDRR; def CV_ # NAME # _B : CVSIMDRR; def CV_ # NAME # _SC_H : CVSIMDRR; def CV_ # NAME # _SC_B : CVSIMDRR; def CV_ # NAME # _SCI_H : CVSIMDRI; def CV_ # NAME # _SCI_B : CVSIMDRI; } multiclass CVSIMDBinaryUnsigned funct5, bit F, bit funct1, string mnemonic> { def CV_ # NAME # _H : CVSIMDRR; def CV_ # NAME # _B : CVSIMDRR; def CV_ # NAME # _SC_H : CVSIMDRR; def CV_ # NAME # _SC_B : CVSIMDRR; def CV_ # NAME # _SCI_H : CVSIMDRU; def CV_ # NAME # _SCI_B : CVSIMDRU; } multiclass CVSIMDShift funct5, bit F, bit funct1, string mnemonic> { def CV_ # NAME # _H : CVSIMDRR; def CV_ # NAME # _B : CVSIMDRR; def CV_ # NAME # _SC_H : CVSIMDRR; def CV_ # NAME # _SC_B : CVSIMDRR; def CV_ # NAME # _SCI_H : CVSIMDRU; def CV_ # NAME # _SCI_B : CVSIMDRU; } multiclass CVSIMDBinarySignedWb funct5, bit F, bit funct1, string mnemonic> { def CV_ # NAME # _H : CVSIMDRRWb; def CV_ # NAME # _B : CVSIMDRRWb; def CV_ # NAME # _SC_H : CVSIMDRRWb; def CV_ # NAME # _SC_B : CVSIMDRRWb; def CV_ # NAME # _SCI_H : CVSIMDRIWb; def CV_ # NAME # _SCI_B : CVSIMDRIWb; } multiclass CVSIMDBinaryUnsignedWb funct5, bit F, bit funct1, string mnemonic> { def CV_ # NAME # _H : CVSIMDRRWb; def CV_ # NAME # _B : CVSIMDRRWb; def CV_ # NAME # _SC_H : CVSIMDRRWb; def CV_ # NAME # _SC_B : CVSIMDRRWb; def CV_ # NAME # _SCI_H : CVSIMDRUWb; def CV_ # NAME # _SCI_B : CVSIMDRUWb; } let Predicates = [HasVendorXCVsimd, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { defm ADD : CVSIMDBinarySigned<0b00000, 0, 0, "add">; defm SUB : CVSIMDBinarySigned<0b00001, 0, 0, "sub">; defm AVG : CVSIMDBinarySigned<0b00010, 0, 0, "avg">; defm AVGU : CVSIMDBinaryUnsigned<0b00011, 0, 0, "avgu">; defm MIN : CVSIMDBinarySigned<0b00100, 0, 0, "min">; defm MINU : CVSIMDBinaryUnsigned<0b00101, 0, 0, "minu">; defm MAX : CVSIMDBinarySigned<0b00110, 0, 0, "max">; defm MAXU : CVSIMDBinaryUnsigned<0b00111, 0, 0, "maxu">; defm SRL : CVSIMDShift<0b01000, 0, 0, "srl">; defm SRA : CVSIMDShift<0b01001, 0, 0, "sra">; defm SLL : CVSIMDShift<0b01010, 0, 0, "sll">; defm OR : CVSIMDBinarySigned<0b01011, 0, 0, "or">; defm XOR : CVSIMDBinarySigned<0b01100, 0, 0, "xor">; defm AND : CVSIMDBinarySigned<0b01101, 0, 0, "and">; def CV_ABS_H : CVSIMDR<0b01110, 0, 0, 0b000, "cv.abs.h">; def CV_ABS_B : CVSIMDR<0b01110, 0, 0, 0b001, "cv.abs.b">; // 0b01111xx: UNDEF defm DOTUP : CVSIMDBinaryUnsigned<0b10000, 0, 0, "dotup">; defm DOTUSP : CVSIMDBinarySigned<0b10001, 0, 0, "dotusp">; defm DOTSP : CVSIMDBinarySigned<0b10010, 0, 0, "dotsp">; defm SDOTUP : CVSIMDBinaryUnsignedWb<0b10011, 0, 0, "sdotup">; defm SDOTUSP : CVSIMDBinarySignedWb<0b10100, 0, 0, "sdotusp">; defm SDOTSP : CVSIMDBinarySignedWb<0b10101, 0, 0, "sdotsp">; // 0b10110xx: UNDEF def CV_EXTRACT_H : CVSIMDRU<0b10111, 0, 0b000, "cv.extract.h">; def CV_EXTRACT_B : CVSIMDRU<0b10111, 0, 0b001, "cv.extract.b">; def CV_EXTRACTU_H : CVSIMDRU<0b10111, 0, 0b010, "cv.extractu.h">; def CV_EXTRACTU_B : CVSIMDRU<0b10111, 0, 0b011, "cv.extractu.b">; def CV_INSERT_H : CVSIMDRUWb<0b10111, 0, 0b100, "cv.insert.h">; def CV_INSERT_B : CVSIMDRUWb<0b10111, 0, 0b101, "cv.insert.b">; def CV_SHUFFLE_H : CVSIMDRR<0b11000, 0, 0, 0b000, "cv.shuffle.h">; def CV_SHUFFLE_B : CVSIMDRR<0b11000, 0, 0, 0b001, "cv.shuffle.b">; def CV_SHUFFLE_SCI_H : CVSIMDRU<0b11000, 0, 0b110, "cv.shuffle.sci.h">; def CV_SHUFFLEI0_SCI_B : CVSIMDRU<0b11000, 0, 0b111, "cv.shufflei0.sci.b">; def CV_SHUFFLEI1_SCI_B : CVSIMDRU<0b11001, 0, 0b111, "cv.shufflei1.sci.b">; def CV_SHUFFLEI2_SCI_B : CVSIMDRU<0b11010, 0, 0b111, "cv.shufflei2.sci.b">; def CV_SHUFFLEI3_SCI_B : CVSIMDRU<0b11011, 0, 0b111, "cv.shufflei3.sci.b">; def CV_SHUFFLE2_H : CVSIMDRRWb<0b11100, 0, 0, 0b000, "cv.shuffle2.h">; def CV_SHUFFLE2_B : CVSIMDRRWb<0b11100, 0, 0, 0b001, "cv.shuffle2.b">; // 0b11101xx: UNDEF def CV_PACK : CVSIMDRR<0b11110, 0, 0, 0b000, "cv.pack">; def CV_PACK_H : CVSIMDRR<0b11110, 0, 1, 0b000, "cv.pack.h">; def CV_PACKHI_B : CVSIMDRRWb<0b11111, 0, 1, 0b001, "cv.packhi.b">; def CV_PACKLO_B : CVSIMDRRWb<0b11111, 0, 0, 0b001, "cv.packlo.b">; defm CMPEQ : CVSIMDBinarySigned<0b00000, 1, 0, "cmpeq">; defm CMPNE : CVSIMDBinarySigned<0b00001, 1, 0, "cmpne">; defm CMPGT : CVSIMDBinarySigned<0b00010, 1, 0, "cmpgt">; defm CMPGE : CVSIMDBinarySigned<0b00011, 1, 0, "cmpge">; defm CMPLT : CVSIMDBinarySigned<0b00100, 1, 0, "cmplt">; defm CMPLE : CVSIMDBinarySigned<0b00101, 1, 0, "cmple">; defm CMPGTU : CVSIMDBinaryUnsigned<0b00110, 1, 0, "cmpgtu">; defm CMPGEU : CVSIMDBinaryUnsigned<0b00111, 1, 0, "cmpgeu">; defm CMPLTU : CVSIMDBinaryUnsigned<0b01000, 1, 0, "cmpltu">; defm CMPLEU : CVSIMDBinaryUnsigned<0b01001, 1, 0, "cmpleu">; def CV_CPLXMUL_R : CVSIMDRRWb<0b01010, 1, 0, 0b000, "cv.cplxmul.r">; def CV_CPLXMUL_I : CVSIMDRRWb<0b01010, 1, 1, 0b000, "cv.cplxmul.i">; def CV_CPLXMUL_R_DIV2 : CVSIMDRRWb<0b01010, 1, 0, 0b010, "cv.cplxmul.r.div2">; def CV_CPLXMUL_I_DIV2 : CVSIMDRRWb<0b01010, 1, 1, 0b010, "cv.cplxmul.i.div2">; def CV_CPLXMUL_R_DIV4 : CVSIMDRRWb<0b01010, 1, 0, 0b100, "cv.cplxmul.r.div4">; def CV_CPLXMUL_I_DIV4 : CVSIMDRRWb<0b01010, 1, 1, 0b100, "cv.cplxmul.i.div4">; def CV_CPLXMUL_R_DIV8 : CVSIMDRRWb<0b01010, 1, 0, 0b110, "cv.cplxmul.r.div8">; def CV_CPLXMUL_I_DIV8 : CVSIMDRRWb<0b01010, 1, 1, 0b110, "cv.cplxmul.i.div8">; def CV_CPLXCONJ : CVSIMDR<0b01011, 1, 0, 0b000, "cv.cplxconj">; // 0b01011xx: UNDEF def CV_SUBROTMJ : CVSIMDRR<0b01100, 1, 0, 0b000, "cv.subrotmj">; def CV_SUBROTMJ_DIV2 : CVSIMDRR<0b01100, 1, 0, 0b010, "cv.subrotmj.div2">; def CV_SUBROTMJ_DIV4 : CVSIMDRR<0b01100, 1, 0, 0b100, "cv.subrotmj.div4">; def CV_SUBROTMJ_DIV8 : CVSIMDRR<0b01100, 1, 0, 0b110, "cv.subrotmj.div8">; def CV_ADD_DIV2 : CVSIMDRR<0b01101, 1, 0, 0b010, "cv.add.div2">; def CV_ADD_DIV4 : CVSIMDRR<0b01101, 1, 0, 0b100, "cv.add.div4">; def CV_ADD_DIV8 : CVSIMDRR<0b01101, 1, 0, 0b110, "cv.add.div8">; def CV_SUB_DIV2 : CVSIMDRR<0b01110, 1, 0, 0b010, "cv.sub.div2">; def CV_SUB_DIV4 : CVSIMDRR<0b01110, 1, 0, 0b100, "cv.sub.div4">; def CV_SUB_DIV8 : CVSIMDRR<0b01110, 1, 0, 0b110, "cv.sub.div8">; } class CVInstImmBranch funct3, dag outs, dag ins, string opcodestr, string argstr> : RVInstB { bits<5> imm5; let rs2 = imm5; let DecoderNamespace = "XCVbi"; } let Predicates = [HasVendorXCVbi, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 0, isBranch = 1, isTerminator = 1 in { // Immediate branching operations def CV_BEQIMM : CVInstImmBranch<0b110, (outs), (ins GPR:$rs1, simm5:$imm5, simm13_lsb0:$imm12), "cv.beqimm", "$rs1, $imm5, $imm12">, Sched<[]>; def CV_BNEIMM : CVInstImmBranch<0b111, (outs), (ins GPR:$rs1, simm5:$imm5, simm13_lsb0:$imm12), "cv.bneimm", "$rs1, $imm5, $imm12">, Sched<[]>; } def CVrrAsmOperand : AsmOperandClass { let Name = "RegReg"; let ParserMethod = "parseRegReg"; let DiagnosticType = "InvalidRegReg"; } def CVrr : Operand, ComplexPattern { let ParserMatchClass = CVrrAsmOperand; let EncoderMethod = "getRegReg"; let DecoderMethod = "decodeRegReg"; let PrintMethod = "printRegReg"; let MIOperandInfo = (ops GPR:$base, GPR:$offset); } class CVLoad_ri_inc funct3, string opcodestr> : RVInstI { let Constraints = "$rs1_wb = $rs1"; let DecoderNamespace = "XCVmem"; } class CVLoad_rr_inc funct7, bits<3> funct3, string opcodestr> : RVInstR { let Constraints = "$rs1_wb = $rs1"; let DecoderNamespace = "XCVmem"; } class CVLoad_rr funct7, bits<3> funct3, string opcodestr> : RVInstR { bits<5> rd; bits<10> cvrr; let Inst{31-25} = funct7; let Inst{24-20} = cvrr{4-0}; let Inst{19-15} = cvrr{9-5}; let Inst{14-12} = funct3; let Inst{11-7} = rd; let DecoderNamespace = "XCVmem"; } let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0, mayLoad = 1, mayStore = 0, Constraints = "$rs1_wb = $rs1" in { // Register-Immediate load with post-increment def CV_LB_ri_inc : CVLoad_ri_inc<0b000, "cv.lb">; def CV_LBU_ri_inc : CVLoad_ri_inc<0b100, "cv.lbu">; def CV_LH_ri_inc : CVLoad_ri_inc<0b001, "cv.lh">; def CV_LHU_ri_inc : CVLoad_ri_inc<0b101, "cv.lhu">; def CV_LW_ri_inc : CVLoad_ri_inc<0b010, "cv.lw">; // Register-Register load with post-increment def CV_LB_rr_inc : CVLoad_rr_inc<0b0000000, 0b011, "cv.lb">; def CV_LBU_rr_inc : CVLoad_rr_inc<0b0001000, 0b011, "cv.lbu">; def CV_LH_rr_inc : CVLoad_rr_inc<0b0000001, 0b011, "cv.lh">; def CV_LHU_rr_inc : CVLoad_rr_inc<0b0001001, 0b011, "cv.lhu">; def CV_LW_rr_inc : CVLoad_rr_inc<0b0000010, 0b011, "cv.lw">; } let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { // Register-Register load def CV_LB_rr : CVLoad_rr<0b0000100, 0b011, "cv.lb">; def CV_LBU_rr : CVLoad_rr<0b0001100, 0b011, "cv.lbu">; def CV_LH_rr : CVLoad_rr<0b0000101, 0b011, "cv.lh">; def CV_LHU_rr : CVLoad_rr<0b0001101, 0b011, "cv.lhu">; def CV_LW_rr : CVLoad_rr<0b0000110, 0b011, "cv.lw">; } class CVStore_ri_inc funct3, string opcodestr> : RVInstS { let Constraints = "$rs1_wb = $rs1"; let DecoderNamespace = "XCVmem"; } class CVStore_rr_inc funct3, bits<7> funct7, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> rs3; bits<5> rs2; bits<5> rs1; let Inst{31-25} = funct7; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rs3; let Inst{6-0} = OPC_CUSTOM_1.Value; let DecoderNamespace = "XCVmem"; } class CVStore_rr funct3, bits<7> funct7, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> rs2; bits<10> cvrr; let Inst{31-25} = funct7; let Inst{24-20} = rs2; let Inst{19-15} = cvrr{9-5}; let Inst{14-12} = funct3; let Inst{11-7} = cvrr{4-0}; let Inst{6-0} = OPC_CUSTOM_1.Value; let DecoderNamespace = "XCVmem"; } let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rs1_wb = $rs1" in { // Register-Immediate store with post-increment def CV_SB_ri_inc : CVStore_ri_inc<0b000, "cv.sb">; def CV_SH_ri_inc : CVStore_ri_inc<0b001, "cv.sh">; def CV_SW_ri_inc : CVStore_ri_inc<0b010, "cv.sw">; // Register-Register store with post-increment def CV_SB_rr_inc : CVStore_rr_inc<0b011, 0b0010000, (outs GPR:$rs1_wb), (ins GPR:$rs2, GPR:$rs1, GPR:$rs3), "cv.sb", "$rs2, (${rs1}), ${rs3}">; def CV_SH_rr_inc : CVStore_rr_inc<0b011, 0b0010001, (outs GPR:$rs1_wb), (ins GPR:$rs2, GPR:$rs1, GPR:$rs3), "cv.sh", "$rs2, (${rs1}), ${rs3}">; def CV_SW_rr_inc : CVStore_rr_inc<0b011, 0b0010010, (outs GPR:$rs1_wb), (ins GPR:$rs2, GPR:$rs1, GPR:$rs3), "cv.sw", "$rs2, (${rs1}), ${rs3}">; } let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { // Register-Register store def CV_SB_rr : CVStore_rr<0b011, 0b0010100, (outs), (ins GPR:$rs2, CVrr:$cvrr), "cv.sb", "$rs2, $cvrr">; def CV_SH_rr : CVStore_rr<0b011, 0b0010101, (outs), (ins GPR:$rs2, CVrr:$cvrr), "cv.sh", "$rs2, $cvrr">; def CV_SW_rr : CVStore_rr<0b011, 0b0010110, (outs), (ins GPR:$rs2, CVrr:$cvrr), "cv.sw", "$rs2, $cvrr">; } let DecoderNamespace = "XCVelw" in class CVLoad_ri funct3, string opcodestr> : RVInstI; let Predicates = [HasVendorXCVelw, IsRV32], hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { // Event load def CV_ELW : CVLoad_ri<0b011, "cv.elw">; } //===----------------------------------------------------------------------===// // Patterns for load & store operations //===----------------------------------------------------------------------===// class CVLdrrPat : Pat<(XLenVT (LoadOp CVrr:$regreg)), (Inst CVrr:$regreg)>; class CVStriPat : Pat<(StoreOp (XLenVT GPR:$rs2), GPR:$rs1, simm12:$imm12), (Inst GPR:$rs2, GPR:$rs1, simm12:$imm12)>; class CVStrriPat : Pat<(StoreOp (XLenVT GPR:$rs2), GPR:$rs1, GPR:$rs3), (Inst GPR:$rs2, GPR:$rs1, GPR:$rs3)>; class CVStrrPat : Pat<(StoreOp (XLenVT GPR:$rs2), CVrr:$regreg), (Inst GPR:$rs2, CVrr:$regreg)>; let Predicates = [HasVendorXCVmem, IsRV32], AddedComplexity = 1 in { def : CVLdrrPat; def : CVLdrrPat; def : CVLdrrPat; def : CVLdrrPat; def : CVLdrrPat; def : CVLdrrPat; def : CVLdrrPat; def : CVStriPat; def : CVStriPat; def : CVStriPat; def : CVStrriPat; def : CVStrriPat; def : CVStrriPat; def : CVStrrPat; def : CVStrrPat; def : CVStrrPat; } def cv_tuimm2 : TImmLeaf(Imm);}]>; def cv_tuimm5 : TImmLeaf(Imm);}]>; def cv_uimm10 : ImmLeaf(Imm);}]>; def CV_LO5: SDNodeXFormgetTargetConstant(N->getZExtValue() & 0x1f, SDLoc(N), N->getValueType(0)); }]>; def CV_HI5: SDNodeXFormgetTargetConstant(N->getZExtValue() >> 5, SDLoc(N), N->getValueType(0)); }]>; def powerOf2Minus1 : ImmLeaf; def trailing1sPlus1 : SDNodeXFormgetTargetConstant( llvm::countr_one(N->getZExtValue()) + 1, SDLoc(N), N->getValueType(0)); }]>; multiclass PatCoreVBitManip { def : PatGprGpr("CV_" # NAME # "R")>; def : Pat<(intr GPR:$rs1, cv_uimm10:$imm), (!cast("CV_" # NAME) GPR:$rs1, (CV_HI5 cv_uimm10:$imm), (CV_LO5 cv_uimm10:$imm))>; } let Predicates = [HasVendorXCVbitmanip, IsRV32] in { defm EXTRACT : PatCoreVBitManip; defm EXTRACTU : PatCoreVBitManip; defm BCLR : PatCoreVBitManip; defm BSET : PatCoreVBitManip; def : Pat<(int_riscv_cv_bitmanip_insert GPR:$rs1, GPR:$rs2, GPR:$rd), (CV_INSERTR GPR:$rd, GPR:$rs1, GPR:$rs2)>; def : Pat<(int_riscv_cv_bitmanip_insert GPR:$rs1, cv_uimm10:$imm, GPR:$rd), (CV_INSERT GPR:$rd, GPR:$rs1, (CV_HI5 cv_uimm10:$imm), (CV_LO5 cv_uimm10:$imm))>; def : PatGpr; def : PatGpr; def : PatGpr; def : PatGpr; def : PatGprGpr; def : Pat<(int_riscv_cv_bitmanip_bitrev GPR:$rs1, cv_tuimm5:$pts, cv_tuimm2:$radix), (CV_BITREV GPR:$rs1, cv_tuimm2:$radix, cv_tuimm5:$pts)>; def : Pat<(bitreverse (XLenVT GPR:$rs)), (CV_BITREV GPR:$rs, 0, 0)>; } class PatCoreVAluGpr : PatGpr("int_riscv_cv_alu_" # intr), !cast("CV_" # asm)>; class PatCoreVAluGprGpr : PatGprGpr("int_riscv_cv_alu_" # intr), !cast("CV_" # asm)>; multiclass PatCoreVAluGprImm { def : PatGprGpr("CV_" # NAME # "R")>; def : Pat<(intr (XLenVT GPR:$rs1), powerOf2Minus1:$upperBound), (!cast("CV_" # NAME) GPR:$rs1, (trailing1sPlus1 imm:$upperBound))>; } multiclass PatCoreVAluGprGprImm { def : Pat<(intr GPR:$rs1, GPR:$rs2, GPR:$rs3), (!cast("CV_" # NAME # "R") GPR:$rs1, GPR:$rs2, GPR:$rs3)>; def : Pat<(intr GPR:$rs1, GPR:$rs2, uimm5:$imm), (!cast("CV_" # NAME) GPR:$rs1, GPR:$rs2, uimm5:$imm)>; } let Predicates = [HasVendorXCValu, IsRV32], AddedComplexity = 1 in { def : PatGpr; def : PatGprGpr; def : PatGprGpr; def : PatGprGpr; def : PatGprGpr; def : PatGprGpr; def : PatGprGpr; def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (CV_EXTHS GPR:$rs1)>; def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (CV_EXTBS GPR:$rs1)>; def : Pat<(and (XLenVT GPR:$rs1), 0xffff), (CV_EXTHZ GPR:$rs1)>; defm CLIP : PatCoreVAluGprImm; defm CLIPU : PatCoreVAluGprImm; defm ADDN : PatCoreVAluGprGprImm; defm ADDUN : PatCoreVAluGprGprImm; defm ADDRN : PatCoreVAluGprGprImm; defm ADDURN : PatCoreVAluGprGprImm; defm SUBN : PatCoreVAluGprGprImm; defm SUBUN : PatCoreVAluGprGprImm; defm SUBRN : PatCoreVAluGprGprImm; defm SUBURN : PatCoreVAluGprGprImm; } // Predicates = [HasVendorXCValu, IsRV32] //===----------------------------------------------------------------------===// // Patterns for immediate branching operations //===----------------------------------------------------------------------===// let Predicates = [HasVendorXCVbi, IsRV32], AddedComplexity = 2 in { def : Pat<(riscv_brcc GPR:$rs1, simm5:$imm5, SETEQ, bb:$imm12), (CV_BEQIMM GPR:$rs1, simm5:$imm5, simm13_lsb0:$imm12)>; def : Pat<(riscv_brcc GPR:$rs1, simm5:$imm5, SETNE, bb:$imm12), (CV_BNEIMM GPR:$rs1, simm5:$imm5, simm13_lsb0:$imm12)>; let usesCustomInserter = 1 in def Select_GPR_Using_CC_Imm : Pseudo<(outs GPR:$dst), (ins GPR:$lhs, simm5:$imm5, ixlenimm:$cc, GPR:$truev, GPR:$falsev), []>; class Selectbi : Pat<(riscv_selectcc_frag:$cc (i32 GPR:$lhs), simm5:$Constant, Cond, (i32 GPR:$truev), GPR:$falsev), (Select_GPR_Using_CC_Imm GPR:$lhs, simm5:$Constant, (IntCCtoRISCVCC $cc), GPR:$truev, GPR:$falsev)>; def : Selectbi; def : Selectbi; } class PatCoreVMacGprGprGpr : Pat<(!cast("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd), (!cast("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>; class PatCoreVMacGprGprGprUimm5 : Pat<(!cast("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd, cv_tuimm5:$imm5), (!cast("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>; class PatCoreVMacGprGprUimm5 : Pat<(!cast("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5), (!cast("CV_" # asm) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>; let Predicates = [HasVendorXCVmac] in { def : PatCoreVMacGprGprGpr<"mac", "MAC">; def : PatCoreVMacGprGprGpr<"msu", "MSU">; def : PatCoreVMacGprGprUimm5<"muluN", "MULUN">; def : PatCoreVMacGprGprUimm5<"mulhhuN", "MULHHUN">; def : PatCoreVMacGprGprUimm5<"mulsN", "MULSN">; def : PatCoreVMacGprGprUimm5<"mulhhsN", "MULHHSN">; def : PatCoreVMacGprGprUimm5<"muluRN", "MULURN">; def : PatCoreVMacGprGprUimm5<"mulhhuRN", "MULHHURN">; def : PatCoreVMacGprGprUimm5<"mulsRN", "MULSRN">; def : PatCoreVMacGprGprUimm5<"mulhhsRN", "MULHHSRN">; def : PatCoreVMacGprGprGprUimm5<"macuN", "MACUN">; def : PatCoreVMacGprGprGprUimm5<"machhuN", "MACHHUN">; def : PatCoreVMacGprGprGprUimm5<"macsN", "MACSN">; def : PatCoreVMacGprGprGprUimm5<"machhsN", "MACHHSN">; def : PatCoreVMacGprGprGprUimm5<"macuRN", "MACURN">; def : PatCoreVMacGprGprGprUimm5<"machhuRN", "MACHHURN">; def : PatCoreVMacGprGprGprUimm5<"macsRN", "MACSRN">; def : PatCoreVMacGprGprGprUimm5<"machhsRN", "MACHHSRN">; }