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