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 StackAdjAsmOperand : AsmOperandClass { 45 let Name = "StackAdj"; 46 let ParserMethod = "parseZcmpStackAdj"; 47 let DiagnosticType = "InvalidStackAdj"; 48 let PredicateMethod = "isSpimm"; 49 let RenderMethod = "addSpimmOperands"; 50} 51 52def NegStackAdjAsmOperand : AsmOperandClass { 53 let Name = "NegStackAdj"; 54 let ParserMethod = "parseZcmpNegStackAdj"; 55 let DiagnosticType = "InvalidStackAdj"; 56 let PredicateMethod = "isSpimm"; 57 let RenderMethod = "addSpimmOperands"; 58} 59 60def rlist : Operand<OtherVT> { 61 let ParserMatchClass = RlistAsmOperand; 62 let PrintMethod = "printRlist"; 63 let DecoderMethod = "decodeZcmpRlist"; 64 let EncoderMethod = "getRlistOpValue"; 65 let MCOperandPredicate = [{ 66 int64_t Imm; 67 if (!MCOp.evaluateAsConstantImm(Imm)) 68 return false; 69 // 0~3 Reserved for EABI 70 return isUInt<4>(Imm) && Imm >= 4; 71 }]; 72} 73 74def stackadj : RISCVOp<OtherVT> { 75 let ParserMatchClass = StackAdjAsmOperand; 76 let PrintMethod = "printStackAdj"; 77 let DecoderMethod = "decodeZcmpSpimm"; 78 let OperandType = "OPERAND_SPIMM"; 79 let MCOperandPredicate = [{ 80 int64_t Imm; 81 if (!MCOp.evaluateAsConstantImm(Imm)) 82 return false; 83 return isShiftedUInt<2, 4>(Imm); 84 }]; 85} 86 87def negstackadj : RISCVOp<OtherVT> { 88 let ParserMatchClass = NegStackAdjAsmOperand; 89 let PrintMethod = "printNegStackAdj"; 90 let DecoderMethod = "decodeZcmpSpimm"; 91 let OperandType = "OPERAND_SPIMM"; 92 let MCOperandPredicate = [{ 93 int64_t Imm; 94 if (!MCOp.evaluateAsConstantImm(Imm)) 95 return false; 96 return isShiftedUInt<2, 4>(Imm); 97 }]; 98} 99 100//===----------------------------------------------------------------------===// 101// Instruction Class Templates 102//===----------------------------------------------------------------------===// 103 104let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 105class CLoadB_ri<bits<6> funct6, string OpcodeStr> 106 : RVInst16CLB<funct6, 0b00, (outs GPRC:$rd), 107 (ins GPRCMem:$rs1, uimm2:$imm), 108 OpcodeStr, "$rd, ${imm}(${rs1})"> { 109 bits<2> imm; 110 111 let Inst{6-5} = imm{0,1}; 112} 113 114let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 115class CLoadH_ri<bits<6> funct6, bit funct1, string OpcodeStr, 116 DAGOperand rty = GPRC> 117 : RVInst16CLH<funct6, funct1, 0b00, (outs rty:$rd), 118 (ins GPRCMem:$rs1, uimm2_lsb0:$imm), 119 OpcodeStr, "$rd, ${imm}(${rs1})"> { 120 bits<2> imm; 121 122 let Inst{5} = imm{1}; 123} 124 125let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 126class CStoreB_rri<bits<6> funct6, string OpcodeStr> 127 : RVInst16CSB<funct6, 0b00, (outs), 128 (ins GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm), 129 OpcodeStr, "$rs2, ${imm}(${rs1})"> { 130 bits<2> imm; 131 132 let Inst{6-5} = imm{0,1}; 133} 134 135let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 136class CStoreH_rri<bits<6> funct6, bit funct1, string OpcodeStr, 137 DAGOperand rty = GPRC> 138 : RVInst16CSH<funct6, funct1, 0b00, (outs), 139 (ins rty:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm), 140 OpcodeStr, "$rs2, ${imm}(${rs1})"> { 141 bits<2> imm; 142 143 let Inst{5} = imm{1}; 144} 145 146let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 147class RVZcArith_r<bits<5> funct5, string OpcodeStr> : 148 RVInst16CU<0b100111, funct5, 0b01, (outs GPRC:$rd_wb), (ins GPRC:$rd), 149 OpcodeStr, "$rd"> { 150 let Constraints = "$rd = $rd_wb"; 151} 152 153class RVInstZcCPPP<bits<5> funct5, string opcodestr, 154 DAGOperand immtype = stackadj> 155 : RVInst16<(outs), (ins rlist:$rlist, immtype:$stackadj), 156 opcodestr, "$rlist, $stackadj", [], InstFormatOther> { 157 bits<4> rlist; 158 bits<16> stackadj; 159 160 let Inst{1-0} = 0b10; 161 let Inst{3-2} = stackadj{5-4}; 162 let Inst{7-4} = rlist; 163 let Inst{12-8} = funct5; 164 let Inst{15-13} = 0b101; 165} 166 167//===----------------------------------------------------------------------===// 168// Instructions 169//===----------------------------------------------------------------------===// 170 171let Predicates = [HasStdExtZcb, HasStdExtZba, IsRV64] in 172def C_ZEXT_W : RVZcArith_r<0b11100 , "c.zext.w">, 173 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 174 175let Predicates = [HasStdExtZcb, HasStdExtZbb] in { 176def C_ZEXT_H : RVZcArith_r<0b11010 , "c.zext.h">, 177 Sched<[WriteIALU, ReadIALU]>; 178def C_SEXT_B : RVZcArith_r<0b11001 , "c.sext.b">, 179 Sched<[WriteIALU, ReadIALU]>; 180def C_SEXT_H : RVZcArith_r<0b11011 , "c.sext.h">, 181 Sched<[WriteIALU, ReadIALU]>; 182} 183 184let Predicates = [HasStdExtZcb] in 185def C_ZEXT_B : RVZcArith_r<0b11000 , "c.zext.b">, 186 Sched<[WriteIALU, ReadIALU]>; 187 188let Predicates = [HasStdExtZcb, HasStdExtZmmul] in 189def C_MUL : CA_ALU<0b100111, 0b10, "c.mul">, 190 Sched<[WriteIMul, ReadIMul, ReadIMul]>; 191 192let Predicates = [HasStdExtZcb] in { 193def C_NOT : RVZcArith_r<0b11101 , "c.not">, 194 Sched<[WriteIALU, ReadIALU]>; 195 196def C_LBU : CLoadB_ri<0b100000, "c.lbu">, 197 Sched<[WriteLDB, ReadMemBase]>; 198def C_LHU : CLoadH_ri<0b100001, 0b0, "c.lhu">, 199 Sched<[WriteLDH, ReadMemBase]>; 200def C_LH : CLoadH_ri<0b100001, 0b1, "c.lh">, 201 Sched<[WriteLDH, ReadMemBase]>; 202 203def C_SB : CStoreB_rri<0b100010, "c.sb">, 204 Sched<[WriteSTB, ReadStoreData, ReadMemBase]>; 205def C_SH : CStoreH_rri<0b100011, 0b0, "c.sh">, 206 Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 207 208// Compressed versions of Zhinx load/store. 209let isCodeGenOnly = 1 in { 210def C_LH_INX : CLoadH_ri<0b100001, 0b1, "c.lh", GPRF16C>, 211 Sched<[WriteLDH, ReadMemBase]>; 212def C_SH_INX : CStoreH_rri<0b100011, 0b0, "c.sh", GPRF16C>, 213 Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 214} 215} // Predicates = [HasStdExtZcb] 216 217// Zcmp 218let DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp], 219 hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 220let Defs = [X10, X11] in 221def CM_MVA01S : RVInst16CA<0b101011, 0b11, 0b10, (outs), 222 (ins SR07:$rs1, SR07:$rs2), "cm.mva01s", "$rs1, $rs2">, 223 Sched<[WriteIALU, WriteIALU, ReadIALU, ReadIALU]>; 224 225let Uses = [X10, X11] in 226def CM_MVSA01 : RVInst16CA<0b101011, 0b01, 0b10, (outs SR07:$rs1, SR07:$rs2), 227 (ins), "cm.mvsa01", "$rs1, $rs2">, 228 Sched<[WriteIALU, WriteIALU, ReadIALU, ReadIALU]>; 229} // DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp]... 230 231let DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp] in { 232let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Uses = [X2], Defs = [X2] in 233def CM_PUSH : RVInstZcCPPP<0b11000, "cm.push", negstackadj>, 234 Sched<[WriteIALU, ReadIALU, ReadStoreData, ReadStoreData, 235 ReadStoreData, ReadStoreData, ReadStoreData, ReadStoreData, 236 ReadStoreData, ReadStoreData, ReadStoreData, ReadStoreData, 237 ReadStoreData, ReadStoreData, ReadStoreData]>; 238 239let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isReturn = 1, 240 Uses = [X2], Defs = [X2] in 241def CM_POPRET : RVInstZcCPPP<0b11110, "cm.popret">, 242 Sched<[WriteIALU, WriteLDW, WriteLDW, WriteLDW, WriteLDW, 243 WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, 244 WriteLDW, WriteLDW, WriteLDW, WriteLDW, ReadIALU]>; 245 246let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isReturn = 1, 247 Uses = [X2], Defs = [X2, X10] in 248def CM_POPRETZ : RVInstZcCPPP<0b11100, "cm.popretz">, 249 Sched<[WriteIALU, WriteIALU, WriteLDW, WriteLDW, WriteLDW, 250 WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, 251 WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, 252 ReadIALU]>; 253 254let hasSideEffects = 0, mayLoad = 1, mayStore = 0, 255 Uses = [X2], Defs = [X2] in 256def CM_POP : RVInstZcCPPP<0b11010, "cm.pop">, 257 Sched<[WriteIALU, WriteLDW, WriteLDW, WriteLDW, WriteLDW, 258 WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, WriteLDW, 259 WriteLDW, WriteLDW, WriteLDW, ReadIALU]>; 260} // DecoderNamespace = "RVZcmp", Predicates = [HasStdExtZcmp]... 261 262let DecoderNamespace = "RVZcmt", Predicates = [HasStdExtZcmt], 263 hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 264def CM_JT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm5:$index), 265 "cm.jt", "$index">{ 266 bits<5> index; 267 268 let Inst{12-7} = 0b000000; 269 let Inst{6-2} = index; 270} 271 272let Defs = [X1] in 273def CM_JALT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm8ge32:$index), 274 "cm.jalt", "$index">{ 275 bits<8> index; 276 277 let Inst{12-10} = 0b000; 278 let Inst{9-2} = index; 279} 280} // DecoderNamespace = "RVZcmt", Predicates = [HasStdExtZcmt]... 281 282 283let Predicates = [HasStdExtZcb, HasStdExtZmmul] in{ 284def : CompressPat<(MUL GPRC:$rs1, GPRC:$rs1, GPRC:$rs2), 285 (C_MUL GPRC:$rs1, GPRC:$rs2)>; 286let isCompressOnly = true in 287def : CompressPat<(MUL GPRC:$rs1, GPRC:$rs2, GPRC:$rs1), 288 (C_MUL GPRC:$rs1, GPRC:$rs2)>; 289} // Predicates = [HasStdExtZcb, HasStdExtZmmul] 290 291let Predicates = [HasStdExtZcb, HasStdExtZbb] in{ 292def : CompressPat<(SEXT_B GPRC:$rs1, GPRC:$rs1), 293 (C_SEXT_B GPRC:$rs1, GPRC:$rs1)>; 294def : CompressPat<(SEXT_H GPRC:$rs1, GPRC:$rs1), 295 (C_SEXT_H GPRC:$rs1, GPRC:$rs1)>; 296} // Predicates = [HasStdExtZcb, HasStdExtZbb] 297 298let Predicates = [HasStdExtZcb, HasStdExtZbb] in{ 299def : CompressPat<(ZEXT_H_RV32 GPRC:$rs1, GPRC:$rs1), 300 (C_ZEXT_H GPRC:$rs1, GPRC:$rs1)>; 301def : CompressPat<(ZEXT_H_RV64 GPRC:$rs1, GPRC:$rs1), 302 (C_ZEXT_H GPRC:$rs1, GPRC:$rs1)>; 303} // Predicates = [HasStdExtZcb, HasStdExtZbb] 304 305let Predicates = [HasStdExtZcb] in{ 306def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, 255), 307 (C_ZEXT_B GPRC:$rs1, GPRC:$rs1)>; 308} // Predicates = [HasStdExtZcb] 309 310let Predicates = [HasStdExtZcb, HasStdExtZba, IsRV64] in{ 311def : CompressPat<(ADD_UW GPRC:$rs1, GPRC:$rs1, X0), 312 (C_ZEXT_W GPRC:$rs1, GPRC:$rs1)>; 313} // Predicates = [HasStdExtZcb, HasStdExtZba, IsRV64] 314 315let Predicates = [HasStdExtZcb] in{ 316def : CompressPat<(XORI GPRC:$rs1, GPRC:$rs1, -1), 317 (C_NOT GPRC:$rs1, GPRC:$rs1)>; 318} 319 320let Predicates = [HasStdExtZcb] in{ 321def : CompressPat<(LBU GPRC:$rd, GPRCMem:$rs1, uimm2:$imm), 322 (C_LBU GPRC:$rd, GPRCMem:$rs1, uimm2:$imm)>; 323def : CompressPat<(LHU GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm), 324 (C_LHU GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 325def : CompressPat<(LH GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm), 326 (C_LH GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 327def : CompressPat<(SB GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm), 328 (C_SB GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm)>; 329def : CompressPat<(SH GPRC:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm), 330 (C_SH GPRC:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 331 332let isCompressOnly = true in { 333def : CompressPat<(LH_INX GPRF16C:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm), 334 (C_LH_INX GPRF16C:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 335def : CompressPat<(SH_INX GPRF16C:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm), 336 (C_SH_INX GPRF16C:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm)>; 337} 338}// Predicates = [HasStdExtZcb] 339 340 341//===----------------------------------------------------------------------===// 342// Pseudo Instructions 343//===----------------------------------------------------------------------===// 344 345let Predicates = [HasStdExtZcb] in { 346def : InstAlias<"c.lbu $rd, (${rs1})",(C_LBU GPRC:$rd, GPRC:$rs1, 0), 0>; 347def : InstAlias<"c.lhu $rd, (${rs1})",(C_LHU GPRC:$rd, GPRC:$rs1, 0), 0>; 348def : InstAlias<"c.lh $rd, (${rs1})", (C_LH GPRC:$rd, GPRC:$rs1, 0), 0>; 349def : InstAlias<"c.sb $rd, (${rs1})", (C_SB GPRC:$rd, GPRC:$rs1, 0), 0>; 350def : InstAlias<"c.sh $rd, (${rs1})", (C_SH GPRC:$rd, GPRC:$rs1, 0), 0>; 351} 352