1//===-- RISCVInstrInfoZc.td - RISC-V 'Zc*' instructions ----*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8/// 9/// This file describes the RISC-V instructions from the 'Zc*' compressed 10/// instruction extensions, version 1.0.3. 11/// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Operand and SDNode transformation definitions. 16//===----------------------------------------------------------------------===// 17 18def uimm2_lsb0 : RISCVOp, 19 ImmLeaf<XLenVT, [{return isShiftedUInt<1, 1>(Imm);}]> { 20 let ParserMatchClass = UImmAsmOperand<2, "Lsb0">; 21 let EncoderMethod = "getImmOpValue"; 22 let DecoderMethod = "decodeUImmOperand<2>"; 23 let OperandType = "OPERAND_UIMM2_LSB0"; 24 let MCOperandPredicate = [{ 25 int64_t Imm; 26 if (!MCOp.evaluateAsConstantImm(Imm)) 27 return false; 28 return isShiftedUInt<1, 1>(Imm); 29 }]; 30} 31 32def uimm8ge32 : RISCVOp { 33 let ParserMatchClass = UImmAsmOperand<8, "GE32">; 34 let DecoderMethod = "decodeUImmOperand<8>"; 35 let OperandType = "OPERAND_UIMM8_GE32"; 36} 37 38def RlistAsmOperand : AsmOperandClass { 39 let Name = "Rlist"; 40 let ParserMethod = "parseReglist"; 41 let DiagnosticType = "InvalidRlist"; 42} 43 44def SpimmAsmOperand : AsmOperandClass { 45 let Name = "Spimm"; 46 let ParserMethod = "parseZcmpSpimm"; 47 let DiagnosticType = "InvalidSpimm"; 48} 49 50def rlist : Operand<OtherVT> { 51 let ParserMatchClass = RlistAsmOperand; 52 let PrintMethod = "printRlist"; 53 let DecoderMethod = "decodeZcmpRlist"; 54 let EncoderMethod = "getRlistOpValue"; 55 let MCOperandPredicate = [{ 56 int64_t Imm; 57 if (!MCOp.evaluateAsConstantImm(Imm)) 58 return false; 59 // 0~3 Reserved for EABI 60 return isUInt<4>(Imm) && Imm >= 4; 61 }]; 62 } 63 64def spimm : Operand<OtherVT> { 65 let ParserMatchClass = SpimmAsmOperand; 66 let PrintMethod = "printSpimm"; 67 let DecoderMethod = "decodeZcmpSpimm"; 68 let MCOperandPredicate = [{ 69 int64_t Imm; 70 if (!MCOp.evaluateAsConstantImm(Imm)) 71 return false; 72 return isShiftedUInt<2, 4>(Imm); 73 }]; 74} 75 76//===----------------------------------------------------------------------===// 77// Instruction Class Templates 78//===----------------------------------------------------------------------===// 79 80let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 81class CLoadB_ri<bits<6> funct6, string OpcodeStr> 82 : RVInst16CLB<funct6, 0b00, (outs GPRC:$rd), 83 (ins GPRCMem:$rs1, uimm2:$imm), 84 OpcodeStr, "$rd, ${imm}(${rs1})"> { 85 bits<2> imm; 86 87 let Inst{6-5} = imm{0,1}; 88} 89 90let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 91class CLoadH_ri<bits<6> funct6, bit funct1, string OpcodeStr> 92 : RVInst16CLH<funct6, funct1, 0b00, (outs GPRC:$rd), 93 (ins GPRCMem:$rs1, uimm2_lsb0:$imm), 94 OpcodeStr, "$rd, ${imm}(${rs1})"> { 95 bits<2> imm; 96 97 let Inst{5} = imm{1}; 98} 99 100let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 101class CStoreB_rri<bits<6> funct6, string OpcodeStr> 102 : RVInst16CSB<funct6, 0b00, (outs), 103 (ins GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm), 104 OpcodeStr, "$rs2, ${imm}(${rs1})"> { 105 bits<2> imm; 106 107 let Inst{6-5} = imm{0,1}; 108} 109 110let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 111class CStoreH_rri<bits<6> funct6, bit funct1, string OpcodeStr> 112 : RVInst16CSH<funct6, funct1, 0b00, (outs), 113 (ins GPRC:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm), 114 OpcodeStr, "$rs2, ${imm}(${rs1})"> { 115 bits<2> imm; 116 117 let Inst{5} = imm{1}; 118} 119 120let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 121class RVZcArith_r<bits<5> funct5, string OpcodeStr> : 122 RVInst16CU<0b100111, funct5, 0b01, (outs GPRC:$rd_wb), (ins GPRC:$rd), 123 OpcodeStr, "$rd"> { 124 let Constraints = "$rd = $rd_wb"; 125} 126 127class RVInstZcCPPP<bits<5> funct5, string opcodestr> 128 : RVInst16<(outs), (ins rlist:$rlist, spimm:$spimm), 129 opcodestr, "$rlist, $spimm", [], InstFormatOther> { 130 bits<4> rlist; 131 bits<16> spimm; 132 133 let Inst{1-0} = 0b10; 134 let Inst{3-2} = spimm{5-4}; 135 let Inst{7-4} = rlist; 136 let Inst{12-8} = funct5; 137 let Inst{15-13} = 0b101; 138} 139 140//===----------------------------------------------------------------------===// 141// Instructions 142//===----------------------------------------------------------------------===// 143 144let Predicates = [HasStdExtZcb, HasStdExtZba, IsRV64] in 145def C_ZEXT_W : RVZcArith_r<0b11100 , "c.zext.w">, 146 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 147 148let Predicates = [HasStdExtZcb, HasStdExtZbb] in { 149def C_ZEXT_H : RVZcArith_r<0b11010 , "c.zext.h">, 150 Sched<[WriteIALU, ReadIALU]>; 151def C_SEXT_B : RVZcArith_r<0b11001 , "c.sext.b">, 152 Sched<[WriteIALU, ReadIALU]>; 153def C_SEXT_H : RVZcArith_r<0b11011 , "c.sext.h">, 154 Sched<[WriteIALU, ReadIALU]>; 155} 156 157let Predicates = [HasStdExtZcb] in 158def C_ZEXT_B : RVZcArith_r<0b11000 , "c.zext.b">, 159 Sched<[WriteIALU, ReadIALU]>; 160 161let Predicates = [HasStdExtZcb, HasStdExtMOrZmmul] in 162def C_MUL : CA_ALU<0b100111, 0b10, "c.mul", GPRC>, 163 Sched<[WriteIMul, ReadIMul, ReadIMul]>; 164 165let Predicates = [HasStdExtZcb] in { 166def C_NOT : RVZcArith_r<0b11101 , "c.not">, 167 Sched<[WriteIALU, ReadIALU]>; 168 169def C_LBU : CLoadB_ri<0b100000, "c.lbu">, 170 Sched<[WriteLDB, ReadMemBase]>; 171def C_LHU : CLoadH_ri<0b100001, 0b0, "c.lhu">, 172 Sched<[WriteLDH, ReadMemBase]>; 173def C_LH : CLoadH_ri<0b100001, 0b1, "c.lh">, 174 Sched<[WriteLDH, ReadMemBase]>; 175 176def C_SB : CStoreB_rri<0b100010, "c.sb">, 177 Sched<[WriteSTB, ReadStoreData, ReadMemBase]>; 178def C_SH : CStoreH_rri<0b100011, 0b0, "c.sh">, 179 Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 180} 181 182// Zcmp 183let DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp], 184 Defs = [X10, X11], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 185def CM_MVA01S : RVInst16CA<0b101011, 0b11, 0b10, (outs), 186 (ins SR07:$rs1, SR07:$rs2), "cm.mva01s", "$rs1, $rs2">; 187 188def CM_MVSA01 : RVInst16CA<0b101011, 0b01, 0b10, (outs SR07:$rs1, SR07:$rs2), 189 (ins), "cm.mvsa01", "$rs1, $rs2">; 190} // DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp]... 191 192let DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp] in { 193let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 194def CM_PUSH : RVInstZcCPPP<0b11000, "cm.push">; 195 196let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 197def CM_POPRET : RVInstZcCPPP<0b11110, "cm.popret">; 198 199let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 200def CM_POPRETZ : RVInstZcCPPP<0b11100, "cm.popretz">; 201 202let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 203def CM_POP : RVInstZcCPPP<0b11010, "cm.pop">; 204} // DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp]... 205 206let DecoderNamespace = "RVZcmt", Predicates = [HasStdExtZcmt], 207 hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 208def CM_JT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm5:$index), 209 "cm.jt", "$index">{ 210 bits<5> index; 211 212 let Inst{12-7} = 0b000000; 213 let Inst{6-2} = index; 214} 215 216let Defs = [X1] in 217def CM_JALT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm8ge32:$index), 218 "cm.jalt", "$index">{ 219 bits<8> index; 220 221 let Inst{12-10} = 0b000; 222 let Inst{9-2} = index; 223} 224} // DecoderNamespace = "RVZcmt", Predicates = [HasStdExtZcmt]... 225 226 227let Predicates = [HasStdExtZcb, HasStdExtMOrZmmul] in{ 228def : CompressPat<(MUL GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 229 (C_MUL GPRC:$rs1, GPRC:$rs2)>; 230let isCompressOnly = true in 231def : CompressPat<(MUL GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 232 (C_MUL GPRC:$rs1, GPRC:$rs2)>; 233} // Predicates = [HasStdExtZcb, HasStdExtMOrZmmul] 234 235let Predicates = [HasStdExtZcb, HasStdExtZbb] in{ 236def : CompressPat<(SEXT_B GPRC:$rs1, GPRC:$rs1), 237 (C_SEXT_B GPRC:$rs1, GPRC:$rs1)>; 238def : CompressPat<(SEXT_H GPRC:$rs1, GPRC:$rs1), 239 (C_SEXT_H GPRC:$rs1, GPRC:$rs1)>; 240} // Predicates = [HasStdExtZcb, HasStdExtZbb] 241 242let Predicates = [HasStdExtZcb, HasStdExtZbb] in{ 243def : CompressPat<(ZEXT_H_RV32 GPRC:$rs1, GPRC:$rs1), 244 (C_ZEXT_H GPRC:$rs1, GPRC:$rs1)>; 245def : CompressPat<(ZEXT_H_RV64 GPRC:$rs1, GPRC:$rs1), 246 (C_ZEXT_H GPRC:$rs1, GPRC:$rs1)>; 247} // Predicates = [HasStdExtZcb, HasStdExtZbb] 248 249let Predicates = [HasStdExtZcb] in{ 250def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, 255), 251 (C_ZEXT_B GPRC:$rs1, GPRC:$rs1)>; 252} // Predicates = [HasStdExtZcb] 253 254let Predicates = [HasStdExtZcb, HasStdExtZba, IsRV64] in{ 255def : CompressPat<(ADD_UW GPRC:$rs1, GPRC:$rs1, X0), 256 (C_ZEXT_W GPRC:$rs1, GPRC:$rs1)>; 257} // Predicates = [HasStdExtZcb, HasStdExtZba, IsRV64] 258 259let Predicates = [HasStdExtZcb] in{ 260def : CompressPat<(XORI GPRC:$rs1, GPRC:$rs1, -1), 261 (C_NOT GPRC:$rs1, GPRC:$rs1)>; 262} 263 264let Predicates = [HasStdExtZcb] in{ 265def : CompressPat<(LBU GPRC:$rd, GPRCMem:$rs1, uimm2:$imm), 266 (C_LBU GPRC:$rd, GPRCMem:$rs1, uimm2:$imm)>; 267def : CompressPat<(LHU GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm), 268 (C_LHU GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 269def : CompressPat<(LH GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm), 270 (C_LH GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 271def : CompressPat<(SB GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm), 272 (C_SB GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm)>; 273def : CompressPat<(SH GPRC:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm), 274 (C_SH GPRC:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 275}// Predicates = [HasStdExtZcb] 276 277 278//===----------------------------------------------------------------------===// 279// Pseudo Instructions 280//===----------------------------------------------------------------------===// 281 282let Predicates = [HasStdExtZcb] in { 283def : InstAlias<"c.lbu $rd, (${rs1})",(C_LBU GPRC:$rd, GPRC:$rs1, 0), 0>; 284def : InstAlias<"c.lhu $rd, (${rs1})",(C_LHU GPRC:$rd, GPRC:$rs1, 0), 0>; 285def : InstAlias<"c.lh $rd, (${rs1})", (C_LH GPRC:$rd, GPRC:$rs1, 0), 0>; 286def : InstAlias<"c.sb $rd, (${rs1})", (C_SB GPRC:$rd, GPRC:$rs1, 0), 0>; 287def : InstAlias<"c.sh $rd, (${rs1})", (C_SH GPRC:$rd, GPRC:$rs1, 0), 0>; 288} 289