1//===-- CSKYInstrInfo.td - Target Description for CSKY -----*- 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 CSKY instructions in TableGen format. 10// 11//===----------------------------------------------------------------------===// 12 13 14//===----------------------------------------------------------------------===// 15// CSKY specific DAG Nodes. 16//===----------------------------------------------------------------------===// 17 18// Target-dependent nodes. 19def CSKY_RET : SDNode<"CSKYISD::RET", SDTNone, 20 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 21 22//===----------------------------------------------------------------------===// 23// Operand and SDNode transformation definitions. 24//===----------------------------------------------------------------------===// 25class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass { 26 let Name = prefix # "Imm" # width # suffix; 27 let RenderMethod = "addImmOperands"; 28 let DiagnosticType = !strconcat("Invalid", Name); 29} 30 31class SImmAsmOperand<int width, string suffix = ""> 32 : ImmAsmOperand<"S", width, suffix> { 33} 34 35class UImmAsmOperand<int width, string suffix = ""> 36 : ImmAsmOperand<"U", width, suffix> { 37} 38 39class OImmAsmOperand<int width, string suffix = ""> 40 : ImmAsmOperand<"O", width, suffix> { 41} 42 43class oimm<int num> : Operand<i32>, 44 ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> { 45 let EncoderMethod = "getOImmOpValue"; 46 let ParserMatchClass = OImmAsmOperand<num>; 47} 48 49class uimm<int num, int shift = 0> : Operand<i32>, 50 ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> { 51 let EncoderMethod = "getImmOpValue<"#shift#">"; 52 let ParserMatchClass = 53 !if(!ne(shift, 0), 54 UImmAsmOperand<num, "Shift"#shift>, 55 UImmAsmOperand<num>); 56} 57 58class simm<int num, int shift = 0> : Operand<i32>, 59 ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> { 60 let EncoderMethod = "getImmOpValue<"#shift#">"; 61 let ParserMatchClass = SImmAsmOperand<num>; 62} 63 64def nimm_XFORM : SDNodeXForm<imm, [{ 65 return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32); 66}]>; 67class nimm<int num> : Operand<i32>, 68 ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> { 69 let ParserMatchClass = UImmAsmOperand<num>; 70} 71 72def uimm32_hi16 : SDNodeXForm<imm, [{ 73 return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF, 74 SDLoc(N), MVT::i32); 75}]>; 76def uimm16_16_xform : Operand<i32>, 77 ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> { 78 let ParserMatchClass = UImmAsmOperand<16>; 79} 80 81def uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> { 82 let EncoderMethod = "getImmShiftOpValue"; 83 let ParserMatchClass = UImmAsmOperand<2>; 84} 85 86def CSKYSymbol : AsmOperandClass { 87 let Name = "CSKYSymbol"; 88 let RenderMethod = "addImmOperands"; 89 let DiagnosticType = "InvalidCSKYSymbol"; 90 let ParserMethod = "parseCSKYSymbol"; 91} 92 93def br_symbol : Operand<iPTR> { 94 let EncoderMethod = 95 "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>"; 96 let ParserMatchClass = CSKYSymbol; 97} 98 99def call_symbol : Operand<iPTR> { 100 let ParserMatchClass = CSKYSymbol; 101 let EncoderMethod = "getCallSymbolOpValue"; 102} 103 104def Constpool : AsmOperandClass { 105 let Name = "ConstpoolSymbol"; 106 let RenderMethod = "addImmOperands"; 107 let DiagnosticType = "InvalidConstpool"; 108 let ParserMethod = "parseConstpoolSymbol"; 109} 110 111def constpool_symbol : Operand<iPTR> { 112 let ParserMatchClass = Constpool; 113 let EncoderMethod = 114 "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>"; 115} 116 117def bare_symbol : Operand<iPTR> { 118 let ParserMatchClass = CSKYSymbol; 119 let EncoderMethod = "getBareSymbolOpValue"; 120} 121 122def oimm12 : oimm<12>; 123def oimm16 : oimm<16>; 124 125def nimm12 : nimm<12>; 126 127def uimm5 : uimm<5>; 128def uimm12 : uimm<12>; 129def uimm12_1 : uimm<12, 1>; 130def uimm12_2 : uimm<12, 2>; 131def uimm16 : uimm<16>; 132 133 134//===----------------------------------------------------------------------===// 135// Instruction Formats 136//===----------------------------------------------------------------------===// 137 138include "CSKYInstrFormats.td" 139 140//===----------------------------------------------------------------------===// 141// Instruction definitions. 142//===----------------------------------------------------------------------===// 143 144class TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>; 145class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 146class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>; 147 148 149 150//===----------------------------------------------------------------------===// 151// Basic ALU instructions. 152//===----------------------------------------------------------------------===// 153 154 def ADDI32 : I_12<0x0, "addi32", add, oimm12>; 155 def SUBI32 : I_12<0x1, "subi32", sub, oimm12>; 156 def ORI32 : I_16_ZX<"ori32", uimm16, 157 [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>; 158 def XORI32 : I_12<0x4, "xori32", xor, uimm12>; 159 def ANDI32 : I_12<0x2, "andi32", and, uimm12>; 160 def ANDNI32 : I_12<0x3, "andni32", and, nimm12>; 161 def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32", 162 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 163 [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>; 164 def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32", 165 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 166 [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>; 167 def ASRI32 : I_5_XZ<0x12, 0x4, "asri32", 168 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 169 [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>; 170 def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32", 171 (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 172 [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>; 173 174 175 def ADDU32 : R_YXZ_SP_F1<0x0, 0x1, 176 BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>; 177 def SUBU32 : R_YXZ_SP_F1<0x0, 0x4, 178 BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">; 179 def MULT32 : R_YXZ_SP_F1<0x21, 0x1, 180 BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>; 181 def AND32 : R_YXZ_SP_F1<0x8, 0x1, 182 BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>; 183 def ANDN32 : R_YXZ_SP_F1<0x8, 0x2, 184 BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">; 185 def OR32: R_YXZ_SP_F1<0x9, 0x1, 186 BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>; 187 def XOR32 : R_YXZ_SP_F1<0x9, 0x2, 188 BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>; 189 def NOR32 : R_YXZ_SP_F1<0x9, 0x4, 190 BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>; 191 def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx), 192 "not32", [(set GPR:$rz, (not GPR:$rx))]>; 193 def LSL32 : R_YXZ_SP_F1<0x10, 0x1, 194 BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">; 195 def LSR32 : R_YXZ_SP_F1<0x10, 0x2, 196 BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">; 197 def ASR32 : R_YXZ_SP_F1<0x10, 0x4, 198 BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">; 199 def ROTL32 : R_YXZ_SP_F1<0x10, 0x8, 200 BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">; 201 202 // TODO: Shift series instr. with carry. 203 204 def IXH32 : R_YXZ_SP_F1<0x2, 0x1, 205 BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">; 206 def IXW32 : R_YXZ_SP_F1<0x2, 0x2, 207 BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">; 208 209 def IXD32 : R_YXZ_SP_F1<0x2, 0x4, 210 BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">; 211 212 let isCommutable = 1 in 213 def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout), 214 (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>; 215 def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout), 216 (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>; 217 218 // TODO: incf32. 219 def DIVS32 : R_YXZ_SP_F1<0x20, 0x2, 220 BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">; 221 def DIVU32 : R_YXZ_SP_F1<0x20, 0x1, 222 BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">; 223 224 def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32", 225 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; 226 def DECLT32 : I_5_XZ<0x4, 0x2, "declt32", 227 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; 228 def DECNE32 : I_5_XZ<0x4, 0x4, "decne32", 229 (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; 230 231 // TODO: s/zext. 232 def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), 233 (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>; 234 def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), 235 (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>; 236 237//===----------------------------------------------------------------------===// 238// Load & Store instructions. 239//===----------------------------------------------------------------------===// 240 241def LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>; 242def LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>; 243def LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>; 244 245 246 def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>; 247 def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>; 248 249 // TODO: LDM and STM. 250 251 252def ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>; 253def ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>; 254def ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>; 255 256 257 def LDR32B : I_LDR<0x0, "ldr32.b">; 258 def LDR32BS : I_LDR<0x4, "ldr32.bs">; 259 def LDR32H : I_LDR<0x1, "ldr32.h">; 260 def LDR32HS : I_LDR<0x5, "ldr32.hs">; 261 def LDR32W : I_LDR<0x2, "ldr32.w">; 262 def STR32B : I_STR<0x0, "str32.b">; 263 def STR32H : I_STR<0x1, "str32.h">; 264 def STR32W : I_STR<0x2, "str32.w">; 265 266 //TODO: SPILL_CARRY and RESTORE_CARRY. 267 268//===----------------------------------------------------------------------===// 269// Compare instructions. 270//===----------------------------------------------------------------------===// 271 272 def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>; 273 def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>; 274 def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>; 275 276 277 def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">; 278 def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">; 279 def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">; 280 281 // TODO: setc and clrc. 282 // TODO: test32 and tstnbz. 283 284//===----------------------------------------------------------------------===// 285// Data move instructions. 286//===----------------------------------------------------------------------===// 287 288 def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>; 289 def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>; 290 def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>; 291 def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>; 292 def MVC32 : R_Z_1<0x1, 0x8, "mvc32">; 293 def MOV32 : R_XZ<0x12, 0x1, "mov32">; 294 295 // TODO: ISEL Pseudo. 296 297 def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">; 298 // TODO: clrf and clrt. 299 def CLRF32 : R_Z_2<0xB, 0x1, "clrf32", []>; 300 def CLRT32 : R_Z_2<0xB, 0x2, "clrt32", []>; 301 302//===----------------------------------------------------------------------===// 303// Branch and call instructions. 304//===----------------------------------------------------------------------===// 305 306let isBranch = 1, isTerminator = 1 in { 307 let isBarrier = 1, isPredicable = 1 in 308 def BR32 : I_16_L<0x0, (outs), (ins br_symbol:$imm16), "br32\t$imm16", 309 [(br bb:$imm16)]>; 310 311 def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16), 312 "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>; 313 def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16), 314 "bf32\t$imm16", []>; 315} 316 317 318 def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>; 319 def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>; 320 def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>; 321 def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>; 322 def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>; 323 def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>; 324 325 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 326 def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register 327 def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16), 328 "jmpi32\t$imm16", []>; 329 } 330 331 let isCall = 1, Defs = [ R15 ] in 332 def JSR32 : I_16_JX<0x7, "jsr32", []>; 333 334 let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in 335 def JSRI32: I_16_L<0x17, (outs), 336 (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>; 337 338 339def BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>; 340 341def BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{ 342 let isCodeGenOnly = 1; 343 let isBranch = 1; 344 let isTerminator = 1; 345 let isBarrier = 1; 346 let isPredicable = 1; 347 let Defs = [ R15 ]; 348} 349 350 351 def RTS32 : I_16_RET<0x6, 0xF, "rts32", [(CSKY_RET)]>; 352 353 354def RTE32 : I_16_RET_I<0, 0, "rte32", []>; 355 356//===----------------------------------------------------------------------===// 357// Symbol address instructions. 358//===----------------------------------------------------------------------===// 359 360def GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset", 361 (outs GPR:$rz), (ins bare_symbol:$offset), []>; 362 363let mayLoad = 1, mayStore = 0 in { 364def LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>; 365let isCodeGenOnly = 1 in 366def LRW32_Gen : I_16_Z_L<0x14, "lrw32", 367 (ins bare_symbol:$src1, constpool_symbol:$imm16), []>; 368} 369 370// TODO: Atomic and fence instructions. 371// TODO: Other operations. 372// TODO: Special instructions. 373// TODO: Pseudo for assembly. 374