Mercurial > hg > CbC > CbC_llvm
view lib/Target/RISCV/RISCVInstrInfo.td @ 124:4fa72497ed5d
fix
author | mir3636 |
---|---|
date | Thu, 30 Nov 2017 20:04:56 +0900 |
parents | 803732b1fca8 |
children | 3a76565eade5 |
line wrap: on
line source
//===-- RISCVInstrInfo.td - Target Description for RISCV ---*- tablegen -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file describes the RISC-V instructions in TableGen format. // //===----------------------------------------------------------------------===// include "RISCVInstrFormats.td" //===----------------------------------------------------------------------===// // RISC-V specific DAG Nodes. //===----------------------------------------------------------------------===// def RetFlag : SDNode<"RISCVISD::RET_FLAG", SDTNone, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; //===----------------------------------------------------------------------===// // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass { let Name = prefix # "Imm" # width # suffix; let RenderMethod = "addImmOperands"; let DiagnosticType = !strconcat("Invalid", Name); } class SImmAsmOperand<int width, string suffix = ""> : ImmAsmOperand<"S", width, suffix> { } class UImmAsmOperand<int width, string suffix = ""> : ImmAsmOperand<"U", width, suffix> { } def FenceArg : AsmOperandClass { let Name = "FenceArg"; let RenderMethod = "addFenceArgOperands"; let DiagnosticType = "InvalidFenceArg"; } def fencearg : Operand<XLenVT> { let ParserMatchClass = FenceArg; let PrintMethod = "printFenceArg"; let DecoderMethod = "decodeUImmOperand<4>"; } def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5>; let DecoderMethod = "decodeUImmOperand<5>"; } def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> { let ParserMatchClass = SImmAsmOperand<12>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<12>"; } def uimm12 : Operand<XLenVT> { let ParserMatchClass = UImmAsmOperand<12>; let DecoderMethod = "decodeUImmOperand<12>"; } // A 13-bit signed immediate where the least significant bit is zero. def simm13_lsb0 : Operand<XLenVT> { let ParserMatchClass = SImmAsmOperand<13, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<13>"; } def uimm20 : Operand<XLenVT> { let ParserMatchClass = UImmAsmOperand<20>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<20>"; } // A 21-bit signed immediate where the least significant bit is zero. def simm21_lsb0 : Operand<XLenVT> { let ParserMatchClass = SImmAsmOperand<21, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<21>"; } //===----------------------------------------------------------------------===// // Instruction Class Templates //===----------------------------------------------------------------------===// let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class BranchCC_rri<bits<3> funct3, string opcodestr> : RVInstB<funct3, OPC_BRANCH, (outs), (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12), opcodestr, "$rs1, $rs2, $imm12"> { let isBranch = 1; let isTerminator = 1; } let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in class Load_ri<bits<3> funct3, string opcodestr> : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), opcodestr, "$rd, ${imm12}(${rs1})">; // Operands for stores are in the order srcreg, base, offset rather than // reflecting the order these fields are specified in the instruction // encoding. let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in class Store_rri<bits<3> funct3, string opcodestr> : RVInstS<funct3, OPC_STORE, (outs), (ins GPR:$rs2, GPR:$rs1, simm12:$imm12), opcodestr, "$rs2, ${imm12}(${rs1})">; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class ALU_ri<bits<3> funct3, string opcodestr> : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), opcodestr, "$rd, $rs1, $imm12">; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class Shift_ri<bit arithshift, bits<3> funct3, string opcodestr> : RVInstIShift<arithshift, funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, uimm5:$shamt), opcodestr, "$rd, $rs1, $shamt">; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr> : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">; let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in class CSR_ir<bits<3> funct3, string opcodestr> : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins uimm12:$imm12, GPR:$rs1), opcodestr, "$rd, $imm12, $rs1">; let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in class CSR_ii<bits<3> funct3, string opcodestr> : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins uimm12:$imm12, uimm5:$rs1), opcodestr, "$rd, $imm12, $rs1">; //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20:$imm20), "lui", "$rd, $imm20">; def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20:$imm20), "auipc", "$rd, $imm20">; let isCall = 1 in def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0:$imm20), "jal", "$rd, $imm20">; let isCall = 1 in def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), "jalr", "$rd, $rs1, $imm12">; } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 def BEQ : BranchCC_rri<0b000, "beq">; def BNE : BranchCC_rri<0b001, "bne">; def BLT : BranchCC_rri<0b100, "blt">; def BGE : BranchCC_rri<0b101, "bge">; def BLTU : BranchCC_rri<0b110, "bltu">; def BGEU : BranchCC_rri<0b111, "bgeu">; def LB : Load_ri<0b000, "lb">; def LH : Load_ri<0b001, "lh">; def LW : Load_ri<0b010, "lw">; def LBU : Load_ri<0b100, "lbu">; def LHU : Load_ri<0b101, "lhu">; def SB : Store_rri<0b000, "sb">; def SH : Store_rri<0b001, "sh">; def SW : Store_rri<0b010, "sw">; def ADDI : ALU_ri<0b000, "addi">; def SLTI : ALU_ri<0b010, "slti">; def SLTIU : ALU_ri<0b011, "sltiu">; def XORI : ALU_ri<0b100, "xori">; def ORI : ALU_ri<0b110, "ori">; def ANDI : ALU_ri<0b111, "andi">; def SLLI : Shift_ri<0, 0b001, "slli">; def SRLI : Shift_ri<0, 0b101, "srli">; def SRAI : Shift_ri<1, 0b101, "srai">; def ADD : ALU_rr<0b0000000, 0b000, "add">; def SUB : ALU_rr<0b0100000, 0b000, "sub">; def SLL : ALU_rr<0b0000000, 0b001, "sll">; def SLT : ALU_rr<0b0000000, 0b010, "slt">; def SLTU : ALU_rr<0b0000000, 0b011, "sltu">; def XOR : ALU_rr<0b0000000, 0b100, "xor">; def SRL : ALU_rr<0b0000000, 0b101, "srl">; def SRA : ALU_rr<0b0100000, 0b101, "sra">; def OR : ALU_rr<0b0000000, 0b110, "or">; def AND : ALU_rr<0b0000000, 0b111, "and">; let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins fencearg:$pred, fencearg:$succ), "fence", "$pred, $succ"> { bits<4> pred; bits<4> succ; let rs1 = 0; let rd = 0; let imm12 = {0b0000,pred,succ}; } def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", ""> { let rs1 = 0; let rd = 0; let imm12 = 0; } def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", ""> { let rs1 = 0; let rd = 0; let imm12 = 0; } def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", ""> { let rs1 = 0; let rd = 0; let imm12 = 1; } } // hasSideEffects = 1, mayLoad = 0, mayStore = 0 def CSRRW : CSR_ir<0b001, "csrrw">; def CSRRS : CSR_ir<0b010, "csrrs">; def CSRRC : CSR_ir<0b011, "csrrc">; def CSRRWI : CSR_ii<0b101, "csrrwi">; def CSRRSI : CSR_ii<0b110, "csrrsi">; def CSRRCI : CSR_ii<0b111, "csrrci">; //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns // // Naming convention: For 'generic' pattern classes, we use the naming // convention PatTy1Ty2. For pattern classes which offer a more complex // expension, prefix the class name, e.g. BccPat. //===----------------------------------------------------------------------===// /// Generic pattern classes class PatGprGpr<SDPatternOperator OpNode, RVInstR Inst> : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>; class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst> : Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>; class PatGprUimm5<SDPatternOperator OpNode, RVInstIShift Inst> : Pat<(OpNode GPR:$rs1, uimm5:$shamt), (Inst GPR:$rs1, uimm5:$shamt)>; /// Simple arithmetic operations def : PatGprGpr<add, ADD>; def : PatGprSimm12<add, ADDI>; def : PatGprGpr<sub, SUB>; def : PatGprGpr<or, OR>; def : PatGprSimm12<or, ORI>; def : PatGprGpr<and, AND>; def : PatGprSimm12<and, ANDI>; def : PatGprGpr<xor, XOR>; def : PatGprSimm12<xor, XORI>; def : PatGprGpr<shl, SLL>; def : PatGprUimm5<shl, SLLI>; def : PatGprGpr<srl, SRL>; def : PatGprUimm5<srl, SRLI>; def : PatGprGpr<sra, SRA>; def : PatGprUimm5<sra, SRAI>; /// Setcc def : PatGprGpr<setlt, SLT>; def : PatGprSimm12<setlt, SLTI>; def : PatGprGpr<setult, SLTU>; def : PatGprSimm12<setult, SLTIU>; /// Branches and jumps let isBarrier = 1, isReturn = 1, isTerminator = 1 in def PseudoRET : Pseudo<(outs), (ins), [(RetFlag)]>, PseudoInstExpansion<(JALR X0, X1, 0)>;