RISCVInstrInfoC.td 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. //===- RISCVInstrInfoC.td - Compressed RISCV instructions -*- tblgen-*-----===//
  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. include "RISCVInstrFormatsC.td"
  9. //===----------------------------------------------------------------------===//
  10. // Operand definitions.
  11. //===----------------------------------------------------------------------===//
  12. def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
  13. let Name = "UImmLog2XLenNonZero";
  14. let RenderMethod = "addImmOperands";
  15. let DiagnosticType = "InvalidUImmLog2XLenNonZero";
  16. }
  17. def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
  18. if (Subtarget->is64Bit())
  19. return isUInt<6>(Imm) && (Imm != 0);
  20. return isUInt<5>(Imm) && (Imm != 0);
  21. }]> {
  22. let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand;
  23. // TODO: should ensure invalid shamt is rejected when decoding.
  24. let DecoderMethod = "decodeUImmOperand<6>";
  25. let OperandType = "OPERAND_UIMMLOG2XLEN_NONZERO";
  26. let OperandNamespace = "RISCVOp";
  27. let MCOperandPredicate = [{
  28. int64_t Imm;
  29. if (!MCOp.evaluateAsConstantImm(Imm))
  30. return false;
  31. if (STI.getTargetTriple().isArch64Bit())
  32. return isUInt<6>(Imm) && (Imm != 0);
  33. return isUInt<5>(Imm) && (Imm != 0);
  34. }];
  35. }
  36. def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
  37. let ParserMatchClass = SImmAsmOperand<6>;
  38. let EncoderMethod = "getImmOpValue";
  39. let DecoderMethod = "decodeSImmOperand<6>";
  40. let OperandType = "OPERAND_SIMM6";
  41. let OperandNamespace = "RISCVOp";
  42. let MCOperandPredicate = [{
  43. int64_t Imm;
  44. if (MCOp.evaluateAsConstantImm(Imm))
  45. return isInt<6>(Imm);
  46. return MCOp.isBareSymbolRef();
  47. }];
  48. }
  49. def simm6nonzero : Operand<XLenVT>,
  50. ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
  51. let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
  52. let EncoderMethod = "getImmOpValue";
  53. let DecoderMethod = "decodeSImmOperand<6>";
  54. let OperandType = "OPERAND_SIMM6_NONZERO";
  55. let OperandNamespace = "RISCVOp";
  56. let MCOperandPredicate = [{
  57. int64_t Imm;
  58. if (MCOp.evaluateAsConstantImm(Imm))
  59. return (Imm != 0) && isInt<6>(Imm);
  60. return MCOp.isBareSymbolRef();
  61. }];
  62. }
  63. def immzero : Operand<XLenVT>,
  64. ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
  65. let ParserMatchClass = ImmZeroAsmOperand;
  66. let OperandType = "OPERAND_ZERO";
  67. let OperandNamespace = "RISCVOp";
  68. }
  69. def CLUIImmAsmOperand : AsmOperandClass {
  70. let Name = "CLUIImm";
  71. let RenderMethod = "addImmOperands";
  72. let DiagnosticType = !strconcat("Invalid", Name);
  73. }
  74. // c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
  75. // The RISC-V ISA describes the constraint as [1, 63], with that value being
  76. // loaded in to bits 17-12 of the destination register and sign extended from
  77. // bit 17. Therefore, this 6-bit immediate can represent values in the ranges
  78. // [1, 31] and [0xfffe0, 0xfffff].
  79. def c_lui_imm : Operand<XLenVT>,
  80. ImmLeaf<XLenVT, [{return (Imm != 0) &&
  81. (isUInt<5>(Imm) ||
  82. (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
  83. let ParserMatchClass = CLUIImmAsmOperand;
  84. let EncoderMethod = "getImmOpValue";
  85. let DecoderMethod = "decodeCLUIImmOperand";
  86. let MCOperandPredicate = [{
  87. int64_t Imm;
  88. if (MCOp.evaluateAsConstantImm(Imm))
  89. return (Imm != 0) && (isUInt<5>(Imm) ||
  90. (Imm >= 0xfffe0 && Imm <= 0xfffff));
  91. return MCOp.isBareSymbolRef();
  92. }];
  93. }
  94. // A 7-bit unsigned immediate where the least significant two bits are zero.
  95. def uimm7_lsb00 : Operand<XLenVT>,
  96. ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
  97. let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
  98. let EncoderMethod = "getImmOpValue";
  99. let DecoderMethod = "decodeUImmOperand<7>";
  100. let OperandType = "OPERAND_UIMM7_LSB00";
  101. let OperandNamespace = "RISCVOp";
  102. let MCOperandPredicate = [{
  103. int64_t Imm;
  104. if (!MCOp.evaluateAsConstantImm(Imm))
  105. return false;
  106. return isShiftedUInt<5, 2>(Imm);
  107. }];
  108. }
  109. // A 8-bit unsigned immediate where the least significant two bits are zero.
  110. def uimm8_lsb00 : Operand<XLenVT>,
  111. ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
  112. let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
  113. let EncoderMethod = "getImmOpValue";
  114. let DecoderMethod = "decodeUImmOperand<8>";
  115. let OperandType = "OPERAND_UIMM8_LSB00";
  116. let OperandNamespace = "RISCVOp";
  117. let MCOperandPredicate = [{
  118. int64_t Imm;
  119. if (!MCOp.evaluateAsConstantImm(Imm))
  120. return false;
  121. return isShiftedUInt<6, 2>(Imm);
  122. }];
  123. }
  124. // A 8-bit unsigned immediate where the least significant three bits are zero.
  125. def uimm8_lsb000 : Operand<XLenVT>,
  126. ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
  127. let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
  128. let EncoderMethod = "getImmOpValue";
  129. let DecoderMethod = "decodeUImmOperand<8>";
  130. let OperandType = "OPERAND_UIMM8_LSB000";
  131. let OperandNamespace = "RISCVOp";
  132. let MCOperandPredicate = [{
  133. int64_t Imm;
  134. if (!MCOp.evaluateAsConstantImm(Imm))
  135. return false;
  136. return isShiftedUInt<5, 3>(Imm);
  137. }];
  138. }
  139. // A 9-bit signed immediate where the least significant bit is zero.
  140. def simm9_lsb0 : Operand<OtherVT>,
  141. ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> {
  142. let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
  143. let PrintMethod = "printBranchOperand";
  144. let EncoderMethod = "getImmOpValueAsr1";
  145. let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
  146. let MCOperandPredicate = [{
  147. int64_t Imm;
  148. if (MCOp.evaluateAsConstantImm(Imm))
  149. return isShiftedInt<8, 1>(Imm);
  150. return MCOp.isBareSymbolRef();
  151. }];
  152. let OperandType = "OPERAND_PCREL";
  153. }
  154. // A 9-bit unsigned immediate where the least significant three bits are zero.
  155. def uimm9_lsb000 : Operand<XLenVT>,
  156. ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
  157. let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
  158. let EncoderMethod = "getImmOpValue";
  159. let DecoderMethod = "decodeUImmOperand<9>";
  160. let MCOperandPredicate = [{
  161. int64_t Imm;
  162. if (!MCOp.evaluateAsConstantImm(Imm))
  163. return false;
  164. return isShiftedUInt<6, 3>(Imm);
  165. }];
  166. }
  167. // A 10-bit unsigned immediate where the least significant two bits are zero
  168. // and the immediate can't be zero.
  169. def uimm10_lsb00nonzero : Operand<XLenVT>,
  170. ImmLeaf<XLenVT,
  171. [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
  172. let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
  173. let EncoderMethod = "getImmOpValue";
  174. let DecoderMethod = "decodeUImmNonZeroOperand<10>";
  175. let MCOperandPredicate = [{
  176. int64_t Imm;
  177. if (!MCOp.evaluateAsConstantImm(Imm))
  178. return false;
  179. return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
  180. }];
  181. }
  182. // A 10-bit signed immediate where the least significant four bits are zero.
  183. def simm10_lsb0000nonzero : Operand<XLenVT>,
  184. ImmLeaf<XLenVT,
  185. [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
  186. let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
  187. let EncoderMethod = "getImmOpValue";
  188. let DecoderMethod = "decodeSImmNonZeroOperand<10>";
  189. let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO";
  190. let OperandNamespace = "RISCVOp";
  191. let MCOperandPredicate = [{
  192. int64_t Imm;
  193. if (!MCOp.evaluateAsConstantImm(Imm))
  194. return false;
  195. return isShiftedInt<6, 4>(Imm) && (Imm != 0);
  196. }];
  197. }
  198. // A 12-bit signed immediate where the least significant bit is zero.
  199. def simm12_lsb0 : Operand<XLenVT>,
  200. ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> {
  201. let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
  202. let PrintMethod = "printBranchOperand";
  203. let EncoderMethod = "getImmOpValueAsr1";
  204. let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
  205. let MCOperandPredicate = [{
  206. int64_t Imm;
  207. if (MCOp.evaluateAsConstantImm(Imm))
  208. return isShiftedInt<11, 1>(Imm);
  209. return MCOp.isBareSymbolRef();
  210. }];
  211. let OperandType = "OPERAND_PCREL";
  212. }
  213. //===----------------------------------------------------------------------===//
  214. // Instruction Class Templates
  215. //===----------------------------------------------------------------------===//
  216. let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
  217. class CStackLoad<bits<3> funct3, string OpcodeStr,
  218. RegisterClass cls, DAGOperand opnd>
  219. : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SPMem:$rs1, opnd:$imm),
  220. OpcodeStr, "$rd, ${imm}(${rs1})">;
  221. let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
  222. class CStackStore<bits<3> funct3, string OpcodeStr,
  223. RegisterClass cls, DAGOperand opnd>
  224. : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SPMem:$rs1, opnd:$imm),
  225. OpcodeStr, "$rs2, ${imm}(${rs1})">;
  226. let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
  227. class CLoad_ri<bits<3> funct3, string OpcodeStr,
  228. RegisterClass cls, DAGOperand opnd>
  229. : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRCMem:$rs1, opnd:$imm),
  230. OpcodeStr, "$rd, ${imm}(${rs1})">;
  231. let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
  232. class CStore_rri<bits<3> funct3, string OpcodeStr,
  233. RegisterClass cls, DAGOperand opnd>
  234. : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2,GPRCMem:$rs1, opnd:$imm),
  235. OpcodeStr, "$rs2, ${imm}(${rs1})">;
  236. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  237. class Bcz<bits<3> funct3, string OpcodeStr,
  238. RegisterClass cls>
  239. : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
  240. OpcodeStr, "$rs1, $imm"> {
  241. let isBranch = 1;
  242. let isTerminator = 1;
  243. let Inst{12} = imm{7};
  244. let Inst{11-10} = imm{3-2};
  245. let Inst{6-5} = imm{6-5};
  246. let Inst{4-3} = imm{1-0};
  247. let Inst{2} = imm{4};
  248. }
  249. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  250. class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
  251. Operand ImmOpnd>
  252. : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
  253. OpcodeStr, "$rs1, $imm"> {
  254. let Constraints = "$rs1 = $rs1_wb";
  255. let Inst{12} = imm{5};
  256. let Inst{11-10} = funct2;
  257. let Inst{6-2} = imm{4-0};
  258. }
  259. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  260. class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
  261. RegisterClass cls>
  262. : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
  263. OpcodeStr, "$rd, $rs2"> {
  264. bits<3> rd;
  265. let Constraints = "$rd = $rd_wb";
  266. let Inst{9-7} = rd;
  267. }
  268. //===----------------------------------------------------------------------===//
  269. // Instructions
  270. //===----------------------------------------------------------------------===//
  271. let Predicates = [HasStdExtCOrZca] in {
  272. let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
  273. def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
  274. (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
  275. "c.addi4spn", "$rd, $rs1, $imm">,
  276. Sched<[WriteIALU, ReadIALU]> {
  277. bits<5> rs1;
  278. let Inst{12-11} = imm{5-4};
  279. let Inst{10-7} = imm{9-6};
  280. let Inst{6} = imm{2};
  281. let Inst{5} = imm{3};
  282. }
  283. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
  284. def C_FLD : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000>,
  285. Sched<[WriteFLD64, ReadMemBase]> {
  286. bits<8> imm;
  287. let Inst{12-10} = imm{5-3};
  288. let Inst{6-5} = imm{7-6};
  289. }
  290. def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>,
  291. Sched<[WriteLDW, ReadMemBase]> {
  292. bits<7> imm;
  293. let Inst{12-10} = imm{5-3};
  294. let Inst{6} = imm{2};
  295. let Inst{5} = imm{6};
  296. }
  297. let DecoderNamespace = "RISCV32Only_",
  298. Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in
  299. def C_FLW : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>,
  300. Sched<[WriteFLD32, ReadMemBase]> {
  301. bits<7> imm;
  302. let Inst{12-10} = imm{5-3};
  303. let Inst{6} = imm{2};
  304. let Inst{5} = imm{6};
  305. }
  306. let Predicates = [HasStdExtCOrZca, IsRV64] in
  307. def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>,
  308. Sched<[WriteLDD, ReadMemBase]> {
  309. bits<8> imm;
  310. let Inst{12-10} = imm{5-3};
  311. let Inst{6-5} = imm{7-6};
  312. }
  313. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
  314. def C_FSD : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000>,
  315. Sched<[WriteFST64, ReadStoreData, ReadMemBase]> {
  316. bits<8> imm;
  317. let Inst{12-10} = imm{5-3};
  318. let Inst{6-5} = imm{7-6};
  319. }
  320. def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>,
  321. Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
  322. bits<7> imm;
  323. let Inst{12-10} = imm{5-3};
  324. let Inst{6} = imm{2};
  325. let Inst{5} = imm{6};
  326. }
  327. let DecoderNamespace = "RISCV32Only_",
  328. Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in
  329. def C_FSW : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>,
  330. Sched<[WriteFST32, ReadStoreData, ReadMemBase]> {
  331. bits<7> imm;
  332. let Inst{12-10} = imm{5-3};
  333. let Inst{6} = imm{2};
  334. let Inst{5} = imm{6};
  335. }
  336. let Predicates = [HasStdExtCOrZca, IsRV64] in
  337. def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>,
  338. Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
  339. bits<8> imm;
  340. let Inst{12-10} = imm{5-3};
  341. let Inst{6-5} = imm{7-6};
  342. }
  343. let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  344. def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">,
  345. Sched<[WriteNop]>
  346. {
  347. let Inst{6-2} = 0;
  348. }
  349. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  350. def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
  351. (ins GPRNoX0:$rd, simm6nonzero:$imm),
  352. "c.addi", "$rd, $imm">,
  353. Sched<[WriteIALU, ReadIALU]> {
  354. let Constraints = "$rd = $rd_wb";
  355. let Inst{6-2} = imm{4-0};
  356. }
  357. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  358. def C_ADDI_NOP : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
  359. (ins GPRX0:$rd, immzero:$imm),
  360. "c.addi", "$rd, $imm">,
  361. Sched<[WriteIALU, ReadIALU]> {
  362. let Constraints = "$rd = $rd_wb";
  363. let Inst{6-2} = 0;
  364. let isAsmParserOnly = 1;
  365. }
  366. let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
  367. DecoderNamespace = "RISCV32Only_", Defs = [X1],
  368. Predicates = [HasStdExtCOrZca, IsRV32] in
  369. def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
  370. "c.jal", "$offset">, Sched<[WriteJal]>;
  371. let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
  372. Predicates = [HasStdExtCOrZca, IsRV64] in
  373. def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
  374. (ins GPRNoX0:$rd, simm6:$imm),
  375. "c.addiw", "$rd, $imm">,
  376. Sched<[WriteIALU32, ReadIALU32]> {
  377. let Constraints = "$rd = $rd_wb";
  378. let Inst{6-2} = imm{4-0};
  379. }
  380. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  381. def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
  382. "c.li", "$rd, $imm">,
  383. Sched<[WriteIALU]> {
  384. let Inst{6-2} = imm{4-0};
  385. }
  386. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  387. def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
  388. (ins SP:$rd, simm10_lsb0000nonzero:$imm),
  389. "c.addi16sp", "$rd, $imm">,
  390. Sched<[WriteIALU, ReadIALU]> {
  391. let Constraints = "$rd = $rd_wb";
  392. let Inst{12} = imm{9};
  393. let Inst{11-7} = 2;
  394. let Inst{6} = imm{4};
  395. let Inst{5} = imm{6};
  396. let Inst{4-3} = imm{8-7};
  397. let Inst{2} = imm{5};
  398. }
  399. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  400. def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
  401. (ins c_lui_imm:$imm),
  402. "c.lui", "$rd, $imm">,
  403. Sched<[WriteIALU]> {
  404. let Inst{6-2} = imm{4-0};
  405. }
  406. def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>,
  407. Sched<[WriteShiftImm, ReadShiftImm]>;
  408. def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>,
  409. Sched<[WriteShiftImm, ReadShiftImm]>;
  410. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  411. def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
  412. "c.andi", "$rs1, $imm">,
  413. Sched<[WriteIALU, ReadIALU]> {
  414. let Constraints = "$rs1 = $rs1_wb";
  415. let Inst{12} = imm{5};
  416. let Inst{11-10} = 0b10;
  417. let Inst{6-2} = imm{4-0};
  418. }
  419. def C_SUB : CS_ALU<0b100011, 0b00, "c.sub", GPRC>,
  420. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  421. def C_XOR : CS_ALU<0b100011, 0b01, "c.xor", GPRC>,
  422. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  423. def C_OR : CS_ALU<0b100011, 0b10, "c.or" , GPRC>,
  424. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  425. def C_AND : CS_ALU<0b100011, 0b11, "c.and", GPRC>,
  426. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  427. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  428. def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>,
  429. Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
  430. def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>,
  431. Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
  432. }
  433. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  434. def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
  435. "c.j", "$offset">, Sched<[WriteJmp]> {
  436. let isBranch = 1;
  437. let isTerminator=1;
  438. let isBarrier=1;
  439. }
  440. def C_BEQZ : Bcz<0b110, "c.beqz", GPRC>, Sched<[WriteJmp]>;
  441. def C_BNEZ : Bcz<0b111, "c.bnez", GPRC>, Sched<[WriteJmp]>;
  442. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  443. def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
  444. (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
  445. "c.slli", "$rd, $imm">,
  446. Sched<[WriteShiftImm, ReadShiftImm]> {
  447. let Constraints = "$rd = $rd_wb";
  448. let Inst{6-2} = imm{4-0};
  449. }
  450. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
  451. def C_FLDSP : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000>,
  452. Sched<[WriteFLD64, ReadMemBase]> {
  453. let Inst{6-5} = imm{4-3};
  454. let Inst{4-2} = imm{8-6};
  455. }
  456. def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>,
  457. Sched<[WriteLDW, ReadMemBase]> {
  458. let Inst{6-4} = imm{4-2};
  459. let Inst{3-2} = imm{7-6};
  460. }
  461. let DecoderNamespace = "RISCV32Only_",
  462. Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in
  463. def C_FLWSP : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>,
  464. Sched<[WriteFLD32, ReadMemBase]> {
  465. let Inst{6-4} = imm{4-2};
  466. let Inst{3-2} = imm{7-6};
  467. }
  468. let Predicates = [HasStdExtCOrZca, IsRV64] in
  469. def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>,
  470. Sched<[WriteLDD, ReadMemBase]> {
  471. let Inst{6-5} = imm{4-3};
  472. let Inst{4-2} = imm{8-6};
  473. }
  474. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  475. def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
  476. "c.jr", "$rs1">, Sched<[WriteJmpReg]> {
  477. let isBranch = 1;
  478. let isBarrier = 1;
  479. let isTerminator = 1;
  480. let isIndirectBranch = 1;
  481. let rs2 = 0;
  482. }
  483. let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1,
  484. isAsCheapAsAMove = 1 in
  485. def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
  486. "c.mv", "$rs1, $rs2">,
  487. Sched<[WriteIALU, ReadIALU]>;
  488. let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
  489. def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">, Sched<[]>;
  490. let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
  491. isCall=1, Defs=[X1], rs2 = 0 in
  492. def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
  493. "c.jalr", "$rs1">, Sched<[WriteJalr, ReadJalr]>;
  494. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  495. def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
  496. (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
  497. "c.add", "$rs1, $rs2">,
  498. Sched<[WriteIALU, ReadIALU, ReadIALU]> {
  499. let Constraints = "$rs1 = $rs1_wb";
  500. }
  501. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in
  502. def C_FSDSP : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000>,
  503. Sched<[WriteFST64, ReadStoreData, ReadMemBase]> {
  504. let Inst{12-10} = imm{5-3};
  505. let Inst{9-7} = imm{8-6};
  506. }
  507. def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>,
  508. Sched<[WriteSTW, ReadStoreData, ReadMemBase]> {
  509. let Inst{12-9} = imm{5-2};
  510. let Inst{8-7} = imm{7-6};
  511. }
  512. let DecoderNamespace = "RISCV32Only_",
  513. Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in
  514. def C_FSWSP : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>,
  515. Sched<[WriteFST32, ReadStoreData, ReadMemBase]> {
  516. let Inst{12-9} = imm{5-2};
  517. let Inst{8-7} = imm{7-6};
  518. }
  519. let Predicates = [HasStdExtCOrZca, IsRV64] in
  520. def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>,
  521. Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
  522. let Inst{12-10} = imm{5-3};
  523. let Inst{9-7} = imm{8-6};
  524. }
  525. // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
  526. // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
  527. let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
  528. def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther>,
  529. Sched<[]> {
  530. let Inst{15-0} = 0;
  531. }
  532. } // Predicates = [HasStdExtCOrZca]
  533. //===----------------------------------------------------------------------===//
  534. // HINT Instructions
  535. //===----------------------------------------------------------------------===//
  536. let Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
  537. mayStore = 0 in
  538. {
  539. let rd = 0 in
  540. def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
  541. "c.nop", "$imm">, Sched<[WriteNop]> {
  542. let Inst{6-2} = imm{4-0};
  543. let DecoderMethod = "decodeRVCInstrSImm";
  544. }
  545. // Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
  546. def C_ADDI_HINT_X0 : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
  547. (ins GPRX0:$rd, simm6nonzero:$imm),
  548. "c.addi", "$rd, $imm">,
  549. Sched<[WriteIALU, ReadIALU]> {
  550. let Constraints = "$rd = $rd_wb";
  551. let Inst{6-2} = imm{4-0};
  552. let isAsmParserOnly = 1;
  553. }
  554. def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
  555. (ins GPRNoX0:$rd, immzero:$imm),
  556. "c.addi", "$rd, $imm">,
  557. Sched<[WriteIALU, ReadIALU]> {
  558. let Constraints = "$rd = $rd_wb";
  559. let Inst{6-2} = 0;
  560. let isAsmParserOnly = 1;
  561. }
  562. def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
  563. "c.li", "$rd, $imm">,
  564. Sched<[WriteIALU]> {
  565. let Inst{6-2} = imm{4-0};
  566. let Inst{11-7} = 0;
  567. let DecoderMethod = "decodeRVCInstrRdSImm";
  568. }
  569. def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
  570. (ins c_lui_imm:$imm),
  571. "c.lui", "$rd, $imm">,
  572. Sched<[WriteIALU]> {
  573. let Inst{6-2} = imm{4-0};
  574. let Inst{11-7} = 0;
  575. let DecoderMethod = "decodeRVCInstrRdSImm";
  576. }
  577. def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
  578. "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]>
  579. {
  580. let Inst{11-7} = 0;
  581. let DecoderMethod = "decodeRVCInstrRdRs2";
  582. }
  583. def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rs1_wb),
  584. (ins GPRX0:$rs1, GPRNoX0:$rs2),
  585. "c.add", "$rs1, $rs2">,
  586. Sched<[WriteIALU, ReadIALU, ReadIALU]> {
  587. let Constraints = "$rs1 = $rs1_wb";
  588. let Inst{11-7} = 0;
  589. let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
  590. }
  591. def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
  592. (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
  593. "c.slli", "$rd, $imm">,
  594. Sched<[WriteShiftImm, ReadShiftImm]> {
  595. let Constraints = "$rd = $rd_wb";
  596. let Inst{6-2} = imm{4-0};
  597. let Inst{11-7} = 0;
  598. let DecoderMethod = "decodeRVCInstrRdRs1UImm";
  599. }
  600. def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
  601. "c.slli64", "$rd">,
  602. Sched<[WriteShiftImm, ReadShiftImm]> {
  603. let Constraints = "$rd = $rd_wb";
  604. let Inst{6-2} = 0;
  605. let Inst{12} = 0;
  606. }
  607. def C_SRLI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
  608. (ins GPRC:$rd),
  609. "c.srli64", "$rd">,
  610. Sched<[WriteShiftImm, ReadShiftImm]> {
  611. let Constraints = "$rd = $rd_wb";
  612. let Inst{6-2} = 0;
  613. let Inst{11-10} = 0;
  614. let Inst{12} = 0;
  615. }
  616. def C_SRAI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
  617. (ins GPRC:$rd),
  618. "c.srai64", "$rd">,
  619. Sched<[WriteShiftImm, ReadShiftImm]> {
  620. let Constraints = "$rd = $rd_wb";
  621. let Inst{6-2} = 0;
  622. let Inst{11-10} = 1;
  623. let Inst{12} = 0;
  624. }
  625. } // Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
  626. // mayStore = 0
  627. //===----------------------------------------------------------------------===//
  628. // Assembler Pseudo Instructions
  629. //===----------------------------------------------------------------------===//
  630. let Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl] in {
  631. def : InstAlias<"c.ntl.p1", (C_ADD_HINT X0, X2)>;
  632. def : InstAlias<"c.ntl.pall", (C_ADD_HINT X0, X3)>;
  633. def : InstAlias<"c.ntl.s1", (C_ADD_HINT X0, X4)>;
  634. def : InstAlias<"c.ntl.all", (C_ADD_HINT X0, X5)>;
  635. } // Predicates = [HasStdExtC, HasRVCHints, HasStdExtZihintntl]
  636. let EmitPriority = 0 in {
  637. let Predicates = [HasStdExtCOrZca] in {
  638. def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRCMem:$rs1, 0)>;
  639. def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRCMem:$rs1, 0)>;
  640. def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SPMem:$rs1, 0)>;
  641. def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SPMem:$rs1, 0)>;
  642. }
  643. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  644. def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRCMem:$rs1, 0)>;
  645. def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRCMem:$rs1, 0)>;
  646. def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SPMem:$rs1, 0)>;
  647. def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SPMem:$rs1, 0)>;
  648. }
  649. let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
  650. def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRCMem:$rs1, 0)>;
  651. def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRCMem:$rs1, 0)>;
  652. def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SPMem:$rs1, 0)>;
  653. def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SPMem:$rs1, 0)>;
  654. }
  655. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
  656. def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRCMem:$rs1, 0)>;
  657. def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRCMem:$rs1, 0)>;
  658. def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SPMem:$rs1, 0)>;
  659. def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SPMem:$rs1, 0)>;
  660. }
  661. } // EmitPriority = 0
  662. //===----------------------------------------------------------------------===/i
  663. // Compress Instruction tablegen backend.
  664. //===----------------------------------------------------------------------===//
  665. // Patterns are defined in the same order the compressed instructions appear
  666. // on page 82 of the ISA manual.
  667. // Quadrant 0
  668. let Predicates = [HasStdExtCOrZca] in {
  669. def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
  670. (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
  671. } // Predicates = [HasStdExtCOrZca]
  672. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
  673. def : CompressPat<(FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
  674. (C_FLD FPR64C:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
  675. } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
  676. let Predicates = [HasStdExtCOrZca] in {
  677. def : CompressPat<(LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
  678. (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
  679. } // Predicates = [HasStdExtCOrZca]
  680. let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
  681. def : CompressPat<(FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
  682. (C_FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
  683. } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
  684. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  685. def : CompressPat<(LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
  686. (C_LD GPRC:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
  687. } // Predicates = [HasStdExtCOrZca, IsRV64]
  688. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
  689. def : CompressPat<(FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
  690. (C_FSD FPR64C:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
  691. } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
  692. let Predicates = [HasStdExtCOrZca] in {
  693. def : CompressPat<(SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
  694. (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
  695. } // Predicates = [HasStdExtCOrZca]
  696. let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
  697. def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
  698. (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
  699. } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
  700. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  701. def : CompressPat<(SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
  702. (C_SD GPRC:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
  703. } // Predicates = [HasStdExtCOrZca, IsRV64]
  704. // Quadrant 1
  705. let Predicates = [HasStdExtCOrZca] in {
  706. def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
  707. def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
  708. (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
  709. } // Predicates = [HasStdExtCOrZca]
  710. let Predicates = [HasStdExtCOrZca, IsRV32] in {
  711. def : CompressPat<(JAL X1, simm12_lsb0:$offset),
  712. (C_JAL simm12_lsb0:$offset)>;
  713. } // Predicates = [HasStdExtCOrZca, IsRV32]
  714. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  715. def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
  716. (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
  717. } // Predicates = [HasStdExtCOrZca, IsRV64]
  718. let Predicates = [HasStdExtCOrZca] in {
  719. def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
  720. (C_LI GPRNoX0:$rd, simm6:$imm)>;
  721. def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
  722. (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
  723. def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
  724. (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
  725. def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
  726. (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
  727. def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
  728. (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
  729. def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
  730. (C_ANDI GPRC:$rs1, simm6:$imm)>;
  731. def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
  732. (C_SUB GPRC:$rs1, GPRC:$rs2)>;
  733. def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
  734. (C_XOR GPRC:$rs1, GPRC:$rs2)>;
  735. let isCompressOnly = true in
  736. def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
  737. (C_XOR GPRC:$rs1, GPRC:$rs2)>;
  738. def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
  739. (C_OR GPRC:$rs1, GPRC:$rs2)>;
  740. let isCompressOnly = true in
  741. def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
  742. (C_OR GPRC:$rs1, GPRC:$rs2)>;
  743. def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
  744. (C_AND GPRC:$rs1, GPRC:$rs2)>;
  745. let isCompressOnly = true in
  746. def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
  747. (C_AND GPRC:$rs1, GPRC:$rs2)>;
  748. } // Predicates = [HasStdExtCOrZca]
  749. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  750. let isCompressOnly = true in
  751. def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
  752. (C_LI GPRNoX0:$rd, simm6:$imm)>;
  753. def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
  754. (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
  755. def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
  756. (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
  757. let isCompressOnly = true in
  758. def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
  759. (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
  760. } // Predicates = [HasStdExtCOrZca, IsRV64]
  761. let Predicates = [HasStdExtCOrZca] in {
  762. def : CompressPat<(JAL X0, simm12_lsb0:$offset),
  763. (C_J simm12_lsb0:$offset)>;
  764. def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
  765. (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
  766. def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
  767. (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
  768. } // Predicates = [HasStdExtCOrZca]
  769. // Quadrant 2
  770. let Predicates = [HasStdExtCOrZca] in {
  771. def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
  772. (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
  773. } // Predicates = [HasStdExtCOrZca]
  774. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
  775. def : CompressPat<(FLD FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
  776. (C_FLDSP FPR64:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
  777. } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
  778. let Predicates = [HasStdExtCOrZca] in {
  779. def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
  780. (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
  781. } // Predicates = [HasStdExtCOrZca]
  782. let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
  783. def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
  784. (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
  785. } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
  786. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  787. def : CompressPat<(LD GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
  788. (C_LDSP GPRNoX0:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
  789. } // Predicates = [HasStdExtCOrZca, IsRV64]
  790. let Predicates = [HasStdExtCOrZca] in {
  791. def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
  792. (C_JR GPRNoX0:$rs1)>;
  793. let isCompressOnly = true in {
  794. def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
  795. (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
  796. def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
  797. (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
  798. }
  799. def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
  800. (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
  801. def : CompressPat<(EBREAK), (C_EBREAK)>;
  802. def : CompressPat<(UNIMP), (C_UNIMP)>;
  803. def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
  804. (C_JALR GPRNoX0:$rs1)>;
  805. def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
  806. (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
  807. let isCompressOnly = true in
  808. def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
  809. (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
  810. } // Predicates = [HasStdExtCOrZca]
  811. let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
  812. def : CompressPat<(FSD FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
  813. (C_FSDSP FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
  814. } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
  815. let Predicates = [HasStdExtCOrZca] in {
  816. def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
  817. (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
  818. } // Predicates = [HasStdExtCOrZca]
  819. let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
  820. def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
  821. (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
  822. } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
  823. let Predicates = [HasStdExtCOrZca, IsRV64] in {
  824. def : CompressPat<(SD GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
  825. (C_SDSP GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
  826. } // Predicates = [HasStdExtCOrZca, IsRV64]