Home | History | Annotate | Download | only in RISCV
      1 //===-- RISCVInstrInfo.td - Target Description for RISCV ---*- tablegen -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the RISC-V instructions in TableGen format.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 include "RISCVInstrFormats.td"
     15 
     16 //===----------------------------------------------------------------------===//
     17 // RISC-V specific DAG Nodes.
     18 //===----------------------------------------------------------------------===//
     19 
     20 def SDT_RISCVCall         : SDTypeProfile<0, -1, [SDTCisVT<0, XLenVT>]>;
     21 def SDT_RISCVCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
     22                                             SDTCisVT<1, i32>]>;
     23 def SDT_RISCVCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
     24                                           SDTCisVT<1, i32>]>;
     25 def SDT_RISCVSelectCC     : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,
     26                                                  SDTCisSameAs<0, 4>,
     27                                                  SDTCisSameAs<4, 5>]>;
     28 
     29 
     30 def Call         : SDNode<"RISCVISD::CALL", SDT_RISCVCall,
     31                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
     32                            SDNPVariadic]>;
     33 def CallSeqStart : SDNode<"ISD::CALLSEQ_START", SDT_RISCVCallSeqStart,
     34                           [SDNPHasChain, SDNPOutGlue]>;
     35 def CallSeqEnd   : SDNode<"ISD::CALLSEQ_END", SDT_RISCVCallSeqEnd,
     36                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
     37 def RetFlag      : SDNode<"RISCVISD::RET_FLAG", SDTNone,
     38                           [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
     39 def URetFlag     : SDNode<"RISCVISD::URET_FLAG", SDTNone,
     40                           [SDNPHasChain, SDNPOptInGlue]>;
     41 def SRetFlag     : SDNode<"RISCVISD::SRET_FLAG", SDTNone,
     42                           [SDNPHasChain, SDNPOptInGlue]>;
     43 def MRetFlag     : SDNode<"RISCVISD::MRET_FLAG", SDTNone,
     44                           [SDNPHasChain, SDNPOptInGlue]>;
     45 def SelectCC     : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC,
     46                           [SDNPInGlue]>;
     47 def Tail         : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
     48                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
     49                            SDNPVariadic]>;
     50 
     51 //===----------------------------------------------------------------------===//
     52 // Operand and SDNode transformation definitions.
     53 //===----------------------------------------------------------------------===//
     54 
     55 class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {
     56   let Name = prefix # "ImmXLen" # suffix;
     57   let RenderMethod = "addImmOperands";
     58   let DiagnosticType = !strconcat("Invalid", Name);
     59 }
     60 
     61 class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
     62   let Name = prefix # "Imm" # width # suffix;
     63   let RenderMethod = "addImmOperands";
     64   let DiagnosticType = !strconcat("Invalid", Name);
     65 }
     66 
     67 class SImmAsmOperand<int width, string suffix = "">
     68     : ImmAsmOperand<"S", width, suffix> {
     69 }
     70 
     71 class UImmAsmOperand<int width, string suffix = "">
     72     : ImmAsmOperand<"U", width, suffix> {
     73 }
     74 
     75 def FenceArg : AsmOperandClass {
     76   let Name = "FenceArg";
     77   let RenderMethod = "addFenceArgOperands";
     78   let DiagnosticType = "InvalidFenceArg";
     79 }
     80 
     81 def fencearg : Operand<XLenVT> {
     82   let ParserMatchClass = FenceArg;
     83   let PrintMethod = "printFenceArg";
     84   let DecoderMethod = "decodeUImmOperand<4>";
     85 }
     86 
     87 def UImmLog2XLenAsmOperand : AsmOperandClass {
     88   let Name = "UImmLog2XLen";
     89   let RenderMethod = "addImmOperands";
     90   let DiagnosticType = "InvalidUImmLog2XLen";
     91 }
     92 
     93 def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{
     94   if (Subtarget->is64Bit())
     95     return isUInt<6>(Imm);
     96   return isUInt<5>(Imm);
     97 }]> {
     98   let ParserMatchClass = UImmLog2XLenAsmOperand;
     99   // TODO: should ensure invalid shamt is rejected when decoding.
    100   let DecoderMethod = "decodeUImmOperand<6>";
    101   let MCOperandPredicate = [{
    102     int64_t Imm;
    103     if (!MCOp.evaluateAsConstantImm(Imm))
    104       return false;
    105     if (STI.getTargetTriple().isArch64Bit())
    106       return  isUInt<6>(Imm);
    107     return isUInt<5>(Imm);
    108   }];
    109 }
    110 
    111 def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
    112   let ParserMatchClass = UImmAsmOperand<5>;
    113   let DecoderMethod = "decodeUImmOperand<5>";
    114 }
    115 
    116 def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
    117   let ParserMatchClass = SImmAsmOperand<12>;
    118   let EncoderMethod = "getImmOpValue";
    119   let DecoderMethod = "decodeSImmOperand<12>";
    120   let MCOperandPredicate = [{
    121     int64_t Imm;
    122     if (MCOp.evaluateAsConstantImm(Imm))
    123       return isInt<12>(Imm);
    124     return MCOp.isBareSymbolRef();
    125   }];
    126 }
    127 
    128 def uimm12 : Operand<XLenVT> {
    129   let ParserMatchClass = UImmAsmOperand<12>;
    130   let DecoderMethod = "decodeUImmOperand<12>";
    131 }
    132 
    133 // A 13-bit signed immediate where the least significant bit is zero.
    134 def simm13_lsb0 : Operand<OtherVT> {
    135   let ParserMatchClass = SImmAsmOperand<13, "Lsb0">;
    136   let EncoderMethod = "getImmOpValueAsr1";
    137   let DecoderMethod = "decodeSImmOperandAndLsl1<13>";
    138   let MCOperandPredicate = [{
    139     int64_t Imm;
    140     if (MCOp.evaluateAsConstantImm(Imm))
    141       return isShiftedInt<12, 1>(Imm);
    142     return MCOp.isBareSymbolRef();
    143   }];
    144 }
    145 
    146 def uimm20 : Operand<XLenVT> {
    147   let ParserMatchClass = UImmAsmOperand<20>;
    148   let EncoderMethod = "getImmOpValue";
    149   let DecoderMethod = "decodeUImmOperand<20>";
    150   let MCOperandPredicate = [{
    151     int64_t Imm;
    152     if (MCOp.evaluateAsConstantImm(Imm))
    153       return isUInt<20>(Imm);
    154     return MCOp.isBareSymbolRef();
    155   }];
    156 }
    157 
    158 // A 21-bit signed immediate where the least significant bit is zero.
    159 def simm21_lsb0 : Operand<OtherVT> {
    160   let ParserMatchClass = SImmAsmOperand<21, "Lsb0">;
    161   let EncoderMethod = "getImmOpValueAsr1";
    162   let DecoderMethod = "decodeSImmOperandAndLsl1<21>";
    163   let MCOperandPredicate = [{
    164     int64_t Imm;
    165     if (MCOp.evaluateAsConstantImm(Imm))
    166       return isShiftedInt<20, 1>(Imm);
    167     return MCOp.isBareSymbolRef();
    168   }];
    169 }
    170 
    171 def BareSymbol : AsmOperandClass {
    172   let Name = "BareSymbol";
    173   let RenderMethod = "addImmOperands";
    174   let DiagnosticType = "InvalidBareSymbol";
    175 }
    176 
    177 // A bare symbol.
    178 def bare_symbol : Operand<XLenVT> {
    179   let ParserMatchClass = BareSymbol;
    180   let MCOperandPredicate = [{
    181      return MCOp.isBareSymbolRef();
    182   }];
    183 }
    184 
    185 // A parameterized register class alternative to i32imm/i64imm from Target.td.
    186 def ixlenimm : Operand<XLenVT> {
    187   let ParserMatchClass = ImmXLenAsmOperand<"">;
    188 }
    189 
    190 // Standalone (codegen-only) immleaf patterns.
    191 def simm32     : ImmLeaf<XLenVT, [{return isInt<32>(Imm);}]>;
    192 def simm32hi20 : ImmLeaf<XLenVT, [{return isShiftedInt<20, 12>(Imm);}]>;
    193 
    194 // Addressing modes.
    195 // Necessary because a frameindex can't be matched directly in a pattern.
    196 def AddrFI : ComplexPattern<iPTR, 1, "SelectAddrFI", [frameindex], []>;
    197 
    198 // Extract least significant 12 bits from an immediate value and sign extend
    199 // them.
    200 def LO12Sext : SDNodeXForm<imm, [{
    201   return CurDAG->getTargetConstant(SignExtend64<12>(N->getZExtValue()),
    202                                    SDLoc(N), N->getValueType(0));
    203 }]>;
    204 
    205 // Extract the most significant 20 bits from an immediate value. Add 1 if bit
    206 // 11 is 1, to compensate for the low 12 bits in the matching immediate addi
    207 // or ld/st being negative.
    208 def HI20 : SDNodeXForm<imm, [{
    209   return CurDAG->getTargetConstant(((N->getZExtValue()+0x800) >> 12) & 0xfffff,
    210                                    SDLoc(N), N->getValueType(0));
    211 }]>;
    212 
    213 //===----------------------------------------------------------------------===//
    214 // Instruction Class Templates
    215 //===----------------------------------------------------------------------===//
    216 
    217 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    218 class BranchCC_rri<bits<3> funct3, string opcodestr>
    219     : RVInstB<funct3, OPC_BRANCH, (outs),
    220               (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12),
    221               opcodestr, "$rs1, $rs2, $imm12"> {
    222   let isBranch = 1;
    223   let isTerminator = 1;
    224 }
    225 
    226 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
    227 class Load_ri<bits<3> funct3, string opcodestr>
    228     : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
    229               opcodestr, "$rd, ${imm12}(${rs1})">;
    230 
    231 // Operands for stores are in the order srcreg, base, offset rather than
    232 // reflecting the order these fields are specified in the instruction
    233 // encoding.
    234 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
    235 class Store_rri<bits<3> funct3, string opcodestr>
    236     : RVInstS<funct3, OPC_STORE, (outs),
    237               (ins GPR:$rs2, GPR:$rs1, simm12:$imm12),
    238               opcodestr, "$rs2, ${imm12}(${rs1})">;
    239 
    240 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    241 class ALU_ri<bits<3> funct3, string opcodestr>
    242     : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
    243               opcodestr, "$rd, $rs1, $imm12">;
    244 
    245 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    246 class Shift_ri<bit arithshift, bits<3> funct3, string opcodestr>
    247     : RVInstIShift<arithshift, funct3, OPC_OP_IMM, (outs GPR:$rd),
    248                    (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
    249                    "$rd, $rs1, $shamt">;
    250 
    251 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    252 class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
    253     : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
    254               opcodestr, "$rd, $rs1, $rs2">;
    255 
    256 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
    257 class CSR_ir<bits<3> funct3, string opcodestr>
    258     : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins uimm12:$imm12, GPR:$rs1),
    259               opcodestr, "$rd, $imm12, $rs1">;
    260 
    261 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
    262 class CSR_ii<bits<3> funct3, string opcodestr>
    263     : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd),
    264               (ins uimm12:$imm12, uimm5:$rs1),
    265               opcodestr, "$rd, $imm12, $rs1">;
    266 
    267 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    268 class ShiftW_ri<bit arithshift, bits<3> funct3, string opcodestr>
    269     : RVInstIShiftW<arithshift, funct3, OPC_OP_IMM_32, (outs GPR:$rd),
    270                     (ins GPR:$rs1, uimm5:$shamt), opcodestr,
    271                     "$rd, $rs1, $shamt">;
    272 
    273 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    274 class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
    275     : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd),
    276               (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
    277 
    278 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
    279 class Priv<string opcodestr, bits<7> funct7>
    280     : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),
    281               opcodestr, "">;
    282 
    283 //===----------------------------------------------------------------------===//
    284 // Instructions
    285 //===----------------------------------------------------------------------===//
    286 
    287 let hasSideEffects = 0, isReMaterializable = 1, mayLoad = 0, mayStore = 0 in {
    288 def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20:$imm20),
    289                   "lui", "$rd, $imm20">;
    290 
    291 def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20:$imm20),
    292                     "auipc", "$rd, $imm20">;
    293 
    294 let isCall = 1 in
    295 def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0:$imm20),
    296                   "jal", "$rd, $imm20">;
    297 
    298 let isCall = 1 in
    299 def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd),
    300                    (ins GPR:$rs1, simm12:$imm12),
    301                    "jalr", "$rd, $rs1, $imm12">;
    302 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
    303 
    304 def BEQ  : BranchCC_rri<0b000, "beq">;
    305 def BNE  : BranchCC_rri<0b001, "bne">;
    306 def BLT  : BranchCC_rri<0b100, "blt">;
    307 def BGE  : BranchCC_rri<0b101, "bge">;
    308 def BLTU : BranchCC_rri<0b110, "bltu">;
    309 def BGEU : BranchCC_rri<0b111, "bgeu">;
    310 
    311 def LB  : Load_ri<0b000, "lb">;
    312 def LH  : Load_ri<0b001, "lh">;
    313 def LW  : Load_ri<0b010, "lw">;
    314 def LBU : Load_ri<0b100, "lbu">;
    315 def LHU : Load_ri<0b101, "lhu">;
    316 
    317 def SB : Store_rri<0b000, "sb">;
    318 def SH : Store_rri<0b001, "sh">;
    319 def SW : Store_rri<0b010, "sw">;
    320 
    321 // ADDI isn't always rematerializable, but isReMaterializable will be used as
    322 // a hint which is verified in isReallyTriviallyReMaterializable.
    323 let isReMaterializable = 1 in
    324 def ADDI  : ALU_ri<0b000, "addi">;
    325 
    326 def SLTI  : ALU_ri<0b010, "slti">;
    327 def SLTIU : ALU_ri<0b011, "sltiu">;
    328 def XORI  : ALU_ri<0b100, "xori">;
    329 def ORI   : ALU_ri<0b110, "ori">;
    330 def ANDI  : ALU_ri<0b111, "andi">;
    331 
    332 def SLLI : Shift_ri<0, 0b001, "slli">;
    333 def SRLI : Shift_ri<0, 0b101, "srli">;
    334 def SRAI : Shift_ri<1, 0b101, "srai">;
    335 
    336 def ADD  : ALU_rr<0b0000000, 0b000, "add">;
    337 def SUB  : ALU_rr<0b0100000, 0b000, "sub">;
    338 def SLL  : ALU_rr<0b0000000, 0b001, "sll">;
    339 def SLT  : ALU_rr<0b0000000, 0b010, "slt">;
    340 def SLTU : ALU_rr<0b0000000, 0b011, "sltu">;
    341 def XOR  : ALU_rr<0b0000000, 0b100, "xor">;
    342 def SRL  : ALU_rr<0b0000000, 0b101, "srl">;
    343 def SRA  : ALU_rr<0b0100000, 0b101, "sra">;
    344 def OR   : ALU_rr<0b0000000, 0b110, "or">;
    345 def AND  : ALU_rr<0b0000000, 0b111, "and">;
    346 
    347 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
    348 def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs),
    349                     (ins fencearg:$pred, fencearg:$succ),
    350                     "fence", "$pred, $succ"> {
    351   bits<4> pred;
    352   bits<4> succ;
    353 
    354   let rs1 = 0;
    355   let rd = 0;
    356   let imm12 = {0b0000,pred,succ};
    357 }
    358 
    359 def FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", ""> {
    360   let rs1 = 0;
    361   let rd = 0;
    362   let imm12 = {0b1000,0b0011,0b0011};
    363 }
    364 
    365 def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", ""> {
    366   let rs1 = 0;
    367   let rd = 0;
    368   let imm12 = 0;
    369 }
    370 
    371 def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", ""> {
    372   let rs1 = 0;
    373   let rd = 0;
    374   let imm12 = 0;
    375 }
    376 
    377 def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", ""> {
    378   let rs1 = 0;
    379   let rd = 0;
    380   let imm12 = 1;
    381 }
    382 } // hasSideEffects = 1, mayLoad = 0, mayStore = 0
    383 
    384 def CSRRW : CSR_ir<0b001, "csrrw">;
    385 def CSRRS : CSR_ir<0b010, "csrrs">;
    386 def CSRRC : CSR_ir<0b011, "csrrc">;
    387 
    388 def CSRRWI : CSR_ii<0b101, "csrrwi">;
    389 def CSRRSI : CSR_ii<0b110, "csrrsi">;
    390 def CSRRCI : CSR_ii<0b111, "csrrci">;
    391 
    392 /// RV64I instructions
    393 
    394 let Predicates = [IsRV64] in {
    395 def LWU   : Load_ri<0b110, "lwu">;
    396 def LD    : Load_ri<0b011, "ld">;
    397 def SD    : Store_rri<0b011, "sd">;
    398 
    399 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
    400 def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd),
    401                     (ins GPR:$rs1, simm12:$imm12),
    402                     "addiw", "$rd, $rs1, $imm12">;
    403 
    404 def SLLIW : ShiftW_ri<0, 0b001, "slliw">;
    405 def SRLIW : ShiftW_ri<0, 0b101, "srliw">;
    406 def SRAIW : ShiftW_ri<1, 0b101, "sraiw">;
    407 
    408 def ADDW  : ALUW_rr<0b0000000, 0b000, "addw">;
    409 def SUBW  : ALUW_rr<0b0100000, 0b000, "subw">;
    410 def SLLW  : ALUW_rr<0b0000000, 0b001, "sllw">;
    411 def SRLW  : ALUW_rr<0b0000000, 0b101, "srlw">;
    412 def SRAW  : ALUW_rr<0b0100000, 0b101, "sraw">;
    413 } // Predicates = [IsRV64]
    414 
    415 //===----------------------------------------------------------------------===//
    416 // Privileged instructions
    417 //===----------------------------------------------------------------------===//
    418 
    419 let isBarrier = 1, isReturn = 1, isTerminator = 1 in {
    420 def URET : Priv<"uret", 0b0000000> {
    421   let rd = 0;
    422   let rs1 = 0;
    423   let rs2 = 0b00010;
    424 }
    425 
    426 def SRET : Priv<"sret", 0b0001000> {
    427   let rd = 0;
    428   let rs1 = 0;
    429   let rs2 = 0b00010;
    430 }
    431 
    432 def MRET : Priv<"mret", 0b0011000> {
    433   let rd = 0;
    434   let rs1 = 0;
    435   let rs2 = 0b00010;
    436 }
    437 } // isBarrier = 1, isReturn = 1, isTerminator = 1
    438 
    439 def WFI : Priv<"wfi", 0b0001000> {
    440   let rd = 0;
    441   let rs1 = 0;
    442   let rs2 = 0b00101;
    443 }
    444 
    445 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
    446 def SFENCE_VMA : RVInstR<0b0001001, 0b000, OPC_SYSTEM, (outs),
    447                          (ins GPR:$rs1, GPR:$rs2),
    448                          "sfence.vma", "$rs1, $rs2"> {
    449   let rd = 0;
    450 }
    451 
    452 //===----------------------------------------------------------------------===//
    453 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
    454 //===----------------------------------------------------------------------===//
    455 
    456 // TODO la
    457 // TODO lb lh lw
    458 // TODO RV64I: ld
    459 // TODO sb sh sw
    460 // TODO RV64I: sd
    461 
    462 def : InstAlias<"nop",           (ADDI      X0,      X0,       0)>;
    463 
    464 // Note that the size is 32 because up to 8 32-bit instructions are needed to
    465 // generate an arbitrary 64-bit immediate. However, the size does not really
    466 // matter since PseudoLI is currently only used in the AsmParser where it gets
    467 // expanded to real instructions immediately.
    468 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
    469     isCodeGenOnly = 0, isAsmParserOnly = 1 in
    470 def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm:$imm), [],
    471                       "li", "$rd, $imm">;
    472 
    473 def : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,       0)>;
    474 def : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;
    475 def : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;
    476 
    477 let Predicates = [IsRV64] in {
    478 def : InstAlias<"negw $rd, $rs",   (SUBW  GPR:$rd,      X0, GPR:$rs)>;
    479 def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs,       0)>;
    480 } // Predicates = [IsRV64]
    481 
    482 def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs,       1)>;
    483 def : InstAlias<"snez $rd, $rs", (SLTU  GPR:$rd,      X0, GPR:$rs)>;
    484 def : InstAlias<"sltz $rd, $rs", (SLT   GPR:$rd, GPR:$rs,      X0)>;
    485 def : InstAlias<"sgtz $rd, $rs", (SLT   GPR:$rd,      X0, GPR:$rs)>;
    486 
    487 // sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu
    488 // form will always be printed. Therefore, set a zero weight.
    489 def : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>;
    490 def : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>;
    491 
    492 def : InstAlias<"beqz $rs, $offset",
    493                 (BEQ GPR:$rs,      X0, simm13_lsb0:$offset)>;
    494 def : InstAlias<"bnez $rs, $offset",
    495                 (BNE GPR:$rs,      X0, simm13_lsb0:$offset)>;
    496 def : InstAlias<"blez $rs, $offset",
    497                 (BGE      X0, GPR:$rs, simm13_lsb0:$offset)>;
    498 def : InstAlias<"bgez $rs, $offset",
    499                 (BGE GPR:$rs,      X0, simm13_lsb0:$offset)>;
    500 def : InstAlias<"bltz $rs, $offset",
    501                 (BLT GPR:$rs,      X0, simm13_lsb0:$offset)>;
    502 def : InstAlias<"bgtz $rs, $offset",
    503                 (BLT      X0, GPR:$rs, simm13_lsb0:$offset)>;
    504 
    505 // Always output the canonical mnemonic for the pseudo branch instructions.
    506 // The GNU tools emit the canonical mnemonic for the branch pseudo instructions
    507 // as well (e.g. "bgt" will be recognised by the assembler but never printed by
    508 // objdump). Match this behaviour by setting a zero weight.
    509 def : InstAlias<"bgt $rs, $rt, $offset",
    510                 (BLT  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
    511 def : InstAlias<"ble $rs, $rt, $offset",
    512                 (BGE  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
    513 def : InstAlias<"bgtu $rs, $rt, $offset",
    514                 (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
    515 def : InstAlias<"bleu $rs, $rt, $offset",
    516                 (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
    517 
    518 // "ret" has more weight since "ret" and "jr" alias the same "jalr" instruction.
    519 def : InstAlias<"j $offset",   (JAL  X0, simm21_lsb0:$offset)>;
    520 def : InstAlias<"jal $offset", (JAL  X1, simm21_lsb0:$offset)>;
    521 def : InstAlias<"jr $rs",      (JALR X0, GPR:$rs, 0)>;
    522 def : InstAlias<"jalr $rs",    (JALR X1, GPR:$rs, 0)>;
    523 def : InstAlias<"ret",         (JALR X0,      X1, 0), 2>;
    524 // TODO call
    525 // TODO tail
    526 
    527 def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw
    528 
    529 // CSR Addresses: 0xC00 == cycle,  0xC01 == time,  0xC02 == instret
    530 //                0xC80 == cycleh, 0xC81 == timeh, 0xC82 == instreth
    531 def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, 0xC02, X0)>;
    532 def : InstAlias<"rdcycle $rd",   (CSRRS GPR:$rd, 0xC00, X0)>;
    533 def : InstAlias<"rdtime $rd",    (CSRRS GPR:$rd, 0xC01, X0)>;
    534 
    535 let Predicates = [IsRV32] in {
    536 def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, 0xC82, X0)>;
    537 def : InstAlias<"rdcycleh $rd",   (CSRRS GPR:$rd, 0xC80, X0)>;
    538 def : InstAlias<"rdtimeh $rd",    (CSRRS GPR:$rd, 0xC81, X0)>;
    539 } // Predicates = [IsRV32]
    540 
    541 def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, uimm12:$csr,      X0)>;
    542 def : InstAlias<"csrw $csr, $rs", (CSRRW      X0, uimm12:$csr, GPR:$rs)>;
    543 def : InstAlias<"csrs $csr, $rs", (CSRRS      X0, uimm12:$csr, GPR:$rs)>;
    544 def : InstAlias<"csrc $csr, $rs", (CSRRC      X0, uimm12:$csr, GPR:$rs)>;
    545 
    546 def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, uimm12:$csr, uimm5:$imm)>;
    547 def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, uimm12:$csr, uimm5:$imm)>;
    548 def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, uimm12:$csr, uimm5:$imm)>;
    549 
    550 def : InstAlias<"sfence.vma",     (SFENCE_VMA      X0, X0)>;
    551 def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>;
    552 
    553 //===----------------------------------------------------------------------===//
    554 // Pseudo-instructions and codegen patterns
    555 //
    556 // Naming convention: For 'generic' pattern classes, we use the naming
    557 // convention PatTy1Ty2. For pattern classes which offer a more complex
    558 // expension, prefix the class name, e.g. BccPat.
    559 //===----------------------------------------------------------------------===//
    560 
    561 /// Generic pattern classes
    562 
    563 class PatGprGpr<SDPatternOperator OpNode, RVInstR Inst>
    564     : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>;
    565 class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>
    566     : Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>;
    567 class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
    568     : Pat<(OpNode GPR:$rs1, uimmlog2xlen:$shamt),
    569           (Inst GPR:$rs1, uimmlog2xlen:$shamt)>;
    570 
    571 /// Predicates
    572 
    573 def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{
    574   return isOrEquivalentToAdd(N);
    575 }]>;
    576 
    577 /// Immediates
    578 
    579 def : Pat<(simm12:$imm), (ADDI X0, simm12:$imm)>;
    580 def : Pat<(simm32hi20:$imm), (LUI (HI20 imm:$imm))>;
    581 def : Pat<(simm32:$imm), (ADDI (LUI (HI20 imm:$imm)), (LO12Sext imm:$imm))>;
    582 
    583 /// Simple arithmetic operations
    584 
    585 def : PatGprGpr<add, ADD>;
    586 def : PatGprSimm12<add, ADDI>;
    587 def : PatGprGpr<sub, SUB>;
    588 def : PatGprGpr<or, OR>;
    589 def : PatGprSimm12<or, ORI>;
    590 def : PatGprGpr<and, AND>;
    591 def : PatGprSimm12<and, ANDI>;
    592 def : PatGprGpr<xor, XOR>;
    593 def : PatGprSimm12<xor, XORI>;
    594 def : PatGprGpr<shl, SLL>;
    595 def : PatGprUimmLog2XLen<shl, SLLI>;
    596 def : PatGprGpr<srl, SRL>;
    597 def : PatGprUimmLog2XLen<srl, SRLI>;
    598 def : PatGprGpr<sra, SRA>;
    599 def : PatGprUimmLog2XLen<sra, SRAI>;
    600 
    601 /// FrameIndex calculations
    602 
    603 def : Pat<(add (i32 AddrFI:$Rs), simm12:$imm12),
    604           (ADDI (i32 AddrFI:$Rs), simm12:$imm12)>;
    605 def : Pat<(IsOrAdd (i32 AddrFI:$Rs), simm12:$imm12),
    606           (ADDI (i32 AddrFI:$Rs), simm12:$imm12)>;
    607 
    608 /// Setcc
    609 
    610 def : PatGprGpr<setlt, SLT>;
    611 def : PatGprSimm12<setlt, SLTI>;
    612 def : PatGprGpr<setult, SLTU>;
    613 def : PatGprSimm12<setult, SLTIU>;
    614 
    615 // Define pattern expansions for setcc operations that aren't directly
    616 // handled by a RISC-V instruction.
    617 def : Pat<(seteq GPR:$rs1, GPR:$rs2), (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>;
    618 def : Pat<(setne GPR:$rs1, GPR:$rs2), (SLTU X0, (XOR GPR:$rs1, GPR:$rs2))>;
    619 def : Pat<(setugt GPR:$rs1, GPR:$rs2), (SLTU GPR:$rs2, GPR:$rs1)>;
    620 def : Pat<(setuge GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>;
    621 def : Pat<(setule GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>;
    622 def : Pat<(setgt GPR:$rs1, GPR:$rs2), (SLT GPR:$rs2, GPR:$rs1)>;
    623 def : Pat<(setge GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>;
    624 def : Pat<(setle GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>;
    625 
    626 let usesCustomInserter = 1 in
    627 class SelectCC_rrirr<RegisterClass valty, RegisterClass cmpty>
    628     : Pseudo<(outs valty:$dst),
    629              (ins cmpty:$lhs, cmpty:$rhs, ixlenimm:$imm,
    630               valty:$truev, valty:$falsev),
    631              [(set valty:$dst, (SelectCC cmpty:$lhs, cmpty:$rhs,
    632               (XLenVT imm:$imm), valty:$truev, valty:$falsev))]>;
    633 
    634 def Select_GPR_Using_CC_GPR : SelectCC_rrirr<GPR, GPR>;
    635 
    636 /// Branches and jumps
    637 
    638 // Match `(brcond (CondOp ..), ..)` and lower to the appropriate RISC-V branch
    639 // instruction.
    640 class BccPat<PatFrag CondOp, RVInstB Inst>
    641     : Pat<(brcond (i32 (CondOp GPR:$rs1, GPR:$rs2)), bb:$imm12),
    642           (Inst GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12)>;
    643 
    644 def : BccPat<seteq, BEQ>;
    645 def : BccPat<setne, BNE>;
    646 def : BccPat<setlt, BLT>;
    647 def : BccPat<setge, BGE>;
    648 def : BccPat<setult, BLTU>;
    649 def : BccPat<setuge, BGEU>;
    650 
    651 class BccSwapPat<PatFrag CondOp, RVInst InstBcc>
    652     : Pat<(brcond (i32 (CondOp GPR:$rs1, GPR:$rs2)), bb:$imm12),
    653           (InstBcc GPR:$rs2, GPR:$rs1, bb:$imm12)>;
    654 
    655 // Condition codes that don't have matching RISC-V branch instructions, but
    656 // are trivially supported by swapping the two input operands
    657 def : BccSwapPat<setgt, BLT>;
    658 def : BccSwapPat<setle, BGE>;
    659 def : BccSwapPat<setugt, BLTU>;
    660 def : BccSwapPat<setule, BGEU>;
    661 
    662 // An extra pattern is needed for a brcond without a setcc (i.e. where the
    663 // condition was calculated elsewhere).
    664 def : Pat<(brcond GPR:$cond, bb:$imm12), (BNE GPR:$cond, X0, bb:$imm12)>;
    665 
    666 let isBarrier = 1, isBranch = 1, isTerminator = 1 in
    667 def PseudoBR : Pseudo<(outs), (ins simm21_lsb0:$imm20), [(br bb:$imm20)]>,
    668                PseudoInstExpansion<(JAL X0, simm21_lsb0:$imm20)>;
    669 
    670 let isCall = 1, Defs=[X1] in
    671 let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
    672 def PseudoBRIND : Pseudo<(outs), (ins GPR:$rs1, simm12:$imm12), []>,
    673                   PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
    674 
    675 def : Pat<(brind GPR:$rs1), (PseudoBRIND GPR:$rs1, 0)>;
    676 def : Pat<(brind (add GPR:$rs1, simm12:$imm12)),
    677           (PseudoBRIND GPR:$rs1, simm12:$imm12)>;
    678 
    679 // PseudoCALL is a pseudo instruction which will eventually expand to auipc
    680 // and jalr while encoding. This is desirable, as an auipc+jalr pair with
    681 // R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker
    682 // if the offset fits in a signed 21-bit immediate.
    683 // Define AsmString to print "call" when compile with -S flag.
    684 // Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
    685 let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in
    686 def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func),
    687                         [(Call tglobaladdr:$func)]> {
    688   let AsmString = "call\t$func";
    689 }
    690 
    691 def : Pat<(Call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
    692 
    693 def : Pat<(URetFlag), (URET X0, X0)>;
    694 def : Pat<(SRetFlag), (SRET X0, X0)>;
    695 def : Pat<(MRetFlag), (MRET X0, X0)>;
    696 
    697 let isCall = 1, Defs = [X1] in
    698 def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rs1), [(Call GPR:$rs1)]>,
    699                          PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
    700 
    701 let isBarrier = 1, isReturn = 1, isTerminator = 1 in
    702 def PseudoRET : Pseudo<(outs), (ins), [(RetFlag)]>,
    703                 PseudoInstExpansion<(JALR X0, X1, 0)>;
    704 
    705 // PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually
    706 // expand to auipc and jalr while encoding.
    707 // Define AsmString to print "tail" when compile with -S flag.
    708 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],
    709     isCodeGenOnly = 0 in
    710 def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst), []> {
    711   let AsmString = "tail\t$dst";
    712 }
    713 
    714 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in
    715 def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1), [(Tail GPRTC:$rs1)]>,
    716                          PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
    717 
    718 def : Pat<(Tail (iPTR tglobaladdr:$dst)),
    719           (PseudoTAIL texternalsym:$dst)>;
    720 def : Pat<(Tail (iPTR texternalsym:$dst)),
    721           (PseudoTAIL texternalsym:$dst)>;
    722 
    723 /// Loads
    724 
    725 multiclass LdPat<PatFrag LoadOp, RVInst Inst> {
    726   def : Pat<(LoadOp GPR:$rs1), (Inst GPR:$rs1, 0)>;
    727   def : Pat<(LoadOp AddrFI:$rs1), (Inst AddrFI:$rs1, 0)>;
    728   def : Pat<(LoadOp (add GPR:$rs1, simm12:$imm12)),
    729             (Inst GPR:$rs1, simm12:$imm12)>;
    730   def : Pat<(LoadOp (add AddrFI:$rs1, simm12:$imm12)),
    731             (Inst AddrFI:$rs1, simm12:$imm12)>;
    732   def : Pat<(LoadOp (IsOrAdd AddrFI:$rs1, simm12:$imm12)),
    733             (Inst AddrFI:$rs1, simm12:$imm12)>;
    734 }
    735 
    736 defm : LdPat<sextloadi8, LB>;
    737 defm : LdPat<extloadi8, LB>;
    738 defm : LdPat<sextloadi16, LH>;
    739 defm : LdPat<extloadi16, LH>;
    740 defm : LdPat<load, LW>;
    741 defm : LdPat<zextloadi8, LBU>;
    742 defm : LdPat<zextloadi16, LHU>;
    743 
    744 /// Stores
    745 
    746 multiclass StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy> {
    747   def : Pat<(StoreOp StTy:$rs2, GPR:$rs1), (Inst StTy:$rs2, GPR:$rs1, 0)>;
    748   def : Pat<(StoreOp StTy:$rs2, AddrFI:$rs1), (Inst StTy:$rs2, AddrFI:$rs1, 0)>;
    749   def : Pat<(StoreOp StTy:$rs2, (add GPR:$rs1, simm12:$imm12)),
    750             (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
    751   def : Pat<(StoreOp StTy:$rs2, (add AddrFI:$rs1, simm12:$imm12)),
    752             (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
    753   def : Pat<(StoreOp StTy:$rs2, (IsOrAdd AddrFI:$rs1, simm12:$imm12)),
    754             (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
    755 }
    756 
    757 defm : StPat<truncstorei8, SB, GPR>;
    758 defm : StPat<truncstorei16, SH, GPR>;
    759 defm : StPat<store, SW, GPR>;
    760 
    761 /// Fences
    762 
    763 // Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set
    764 // Manual: Volume I.
    765 
    766 // fence acquire -> fence r, rw
    767 def : Pat<(atomic_fence (i32 4), (imm)), (FENCE 0b10, 0b11)>;
    768 // fence release -> fence rw, w
    769 def : Pat<(atomic_fence (i32 5), (imm)), (FENCE 0b11, 0b1)>;
    770 // fence acq_rel -> fence.tso
    771 def : Pat<(atomic_fence (i32 6), (imm)), (FENCE_TSO)>;
    772 // fence seq_cst -> fence rw, rw
    773 def : Pat<(atomic_fence (i32 7), (imm)), (FENCE 0b11, 0b11)>;
    774 
    775 // Lowering for atomic load and store is defined in RISCVInstrInfoA.td.
    776 // Although these are lowered to fence+load/store instructions defined in the
    777 // base RV32I/RV64I ISA, this lowering is only used when the A extension is
    778 // present. This is necessary as it isn't valid to mix __atomic_* libcalls
    779 // with inline atomic operations for the same object.
    780 
    781 /// Other pseudo-instructions
    782 
    783 // Pessimistically assume the stack pointer will be clobbered
    784 let Defs = [X2], Uses = [X2] in {
    785 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
    786                               [(CallSeqStart timm:$amt1, timm:$amt2)]>;
    787 def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
    788                               [(CallSeqEnd timm:$amt1, timm:$amt2)]>;
    789 } // Defs = [X2], Uses = [X2]
    790 
    791 //===----------------------------------------------------------------------===//
    792 // Standard extensions
    793 //===----------------------------------------------------------------------===//
    794 
    795 include "RISCVInstrInfoM.td"
    796 include "RISCVInstrInfoA.td"
    797 include "RISCVInstrInfoF.td"
    798 include "RISCVInstrInfoD.td"
    799 include "RISCVInstrInfoC.td"
    800