1e8d8bef9SDimitry Andric//===-- CSKYInstrInfo.td - Target Description for CSKY -----*- tablegen -*-===// 2e8d8bef9SDimitry Andric// 3e8d8bef9SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric// 7e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric// 9e8d8bef9SDimitry Andric// This file describes the CSKY instructions in TableGen format. 10e8d8bef9SDimitry Andric// 11e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 12e8d8bef9SDimitry Andric 13e8d8bef9SDimitry Andric 14e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 15e8d8bef9SDimitry Andric// CSKY specific DAG Nodes. 16e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 17e8d8bef9SDimitry Andric 1804eeddc0SDimitry Andric// Target-independent type requirements, but with target-specific formats. 19349cc55cSDimitry Andricdef SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, 20349cc55cSDimitry Andric SDTCisVT<1, i32>]>; 21349cc55cSDimitry Andric 22349cc55cSDimitry Andricdef SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, 23349cc55cSDimitry Andric SDTCisVT<1, i32>]>; 24349cc55cSDimitry Andric 2504eeddc0SDimitry Andricdef SDT_CSKYCall : SDTypeProfile<0, 2, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 2604eeddc0SDimitry Andric 2704eeddc0SDimitry Andricdef SDT_CSKYCallReg : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; 2804eeddc0SDimitry Andric 2904eeddc0SDimitry Andricdef SDT_CSKY_LOADADDR : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, 3004eeddc0SDimitry Andric SDTCisVT<1, iPTR>, SDTCisVT<2, iPTR>]>; 3104eeddc0SDimitry Andric 32349cc55cSDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, 33349cc55cSDimitry Andric [SDNPHasChain, SDNPOutGlue]>; 34349cc55cSDimitry Andricdef callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, 35349cc55cSDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 36349cc55cSDimitry Andric 37fe6060f1SDimitry Andricdef CSKY_RET : SDNode<"CSKYISD::RET", SDTNone, 38fe6060f1SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 39e8d8bef9SDimitry Andric 4004eeddc0SDimitry Andricdef CSKY_CALL : SDNode<"CSKYISD::CALL", SDT_CSKYCall, 4104eeddc0SDimitry Andric [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; 4204eeddc0SDimitry Andric 4304eeddc0SDimitry Andricdef CSKY_CALLReg : SDNode<"CSKYISD::CALLReg", SDT_CSKYCallReg, 4404eeddc0SDimitry Andric [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; 4504eeddc0SDimitry Andric 4604eeddc0SDimitry Andricdef CSKY_TAIL : SDNode<"CSKYISD::TAIL", SDT_CSKYCall, 4704eeddc0SDimitry Andric [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; 4804eeddc0SDimitry Andric 4904eeddc0SDimitry Andricdef CSKY_TAILReg : SDNode<"CSKYISD::TAILReg", SDT_CSKYCallReg, 5004eeddc0SDimitry Andric [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; 5104eeddc0SDimitry Andric 5204eeddc0SDimitry Andricdef CSKY_LOAD_ADDR : SDNode<"CSKYISD::LOAD_ADDR", SDT_CSKY_LOADADDR>; 5304eeddc0SDimitry Andric 54e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 55e8d8bef9SDimitry Andric// Operand and SDNode transformation definitions. 56e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 57fe6060f1SDimitry Andricclass ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass { 58fe6060f1SDimitry Andric let Name = prefix # "Imm" # width # suffix; 59fe6060f1SDimitry Andric let RenderMethod = "addImmOperands"; 60fe6060f1SDimitry Andric let DiagnosticType = !strconcat("Invalid", Name); 61fe6060f1SDimitry Andric} 62fe6060f1SDimitry Andric 63fe6060f1SDimitry Andricclass SImmAsmOperand<int width, string suffix = ""> 64fe6060f1SDimitry Andric : ImmAsmOperand<"S", width, suffix> { 65fe6060f1SDimitry Andric} 66fe6060f1SDimitry Andric 67fe6060f1SDimitry Andricclass UImmAsmOperand<int width, string suffix = ""> 68fe6060f1SDimitry Andric : ImmAsmOperand<"U", width, suffix> { 69fe6060f1SDimitry Andric} 70fe6060f1SDimitry Andric 71fe6060f1SDimitry Andricclass OImmAsmOperand<int width, string suffix = ""> 72fe6060f1SDimitry Andric : ImmAsmOperand<"O", width, suffix> { 73fe6060f1SDimitry Andric} 74e8d8bef9SDimitry Andric 750eae32dcSDimitry Andricdef to_tframeindex : SDNodeXForm<frameindex, [{ 760eae32dcSDimitry Andric auto FI = cast<FrameIndexSDNode>(N); 770eae32dcSDimitry Andric return CurDAG->getTargetFrameIndex(FI->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout())); 780eae32dcSDimitry Andric}]>; 790eae32dcSDimitry Andric 8004eeddc0SDimitry Andricdef to_tconstpool : SDNodeXForm<constpool, [{ 8104eeddc0SDimitry Andric auto CP = cast<ConstantPoolSDNode>(N); 8204eeddc0SDimitry Andric return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()), 8304eeddc0SDimitry Andric CP->getAlign(), CP->getOffset(), CSKYII::MO_None); 8404eeddc0SDimitry Andric}]>; 8504eeddc0SDimitry Andric 8604eeddc0SDimitry Andricdef to_tconstpool_hi16 : SDNodeXForm<constpool, [{ 8704eeddc0SDimitry Andric auto CP = cast<ConstantPoolSDNode>(N); 8804eeddc0SDimitry Andric return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()), 8904eeddc0SDimitry Andric CP->getAlign(), CP->getOffset(), CSKYII::MO_ADDR_HI16); 9004eeddc0SDimitry Andric}]>; 9104eeddc0SDimitry Andric 9204eeddc0SDimitry Andricdef to_tconstpool_lo16 : SDNodeXForm<constpool, [{ 9304eeddc0SDimitry Andric auto CP = cast<ConstantPoolSDNode>(N); 9404eeddc0SDimitry Andric return CurDAG->getTargetConstantPool(CP->getConstVal(), TLI->getPointerTy(CurDAG->getDataLayout()), 9504eeddc0SDimitry Andric CP->getAlign(), CP->getOffset(), CSKYII::MO_ADDR_LO16); 9604eeddc0SDimitry Andric}]>; 9704eeddc0SDimitry Andric 98e8d8bef9SDimitry Andricclass oimm<int num> : Operand<i32>, 99e8d8bef9SDimitry Andric ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> { 100e8d8bef9SDimitry Andric let EncoderMethod = "getOImmOpValue"; 101fe6060f1SDimitry Andric let ParserMatchClass = OImmAsmOperand<num>; 102349cc55cSDimitry Andric let DecoderMethod = "decodeOImmOperand<"#num#">"; 103e8d8bef9SDimitry Andric} 104e8d8bef9SDimitry Andric 10506c3fb27SDimitry Andricdef imm_neg_XFORM : SDNodeXForm<imm, [{ 10606c3fb27SDimitry Andric return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32); 10706c3fb27SDimitry Andric}]>; 10806c3fb27SDimitry Andric 10906c3fb27SDimitry Andricclass oimm_neg<int num> : Operand<i32>, 11006c3fb27SDimitry Andric ImmLeaf<i32, "return isUInt<"#num#">(-Imm - 1);"> { 11106c3fb27SDimitry Andric} 11206c3fb27SDimitry Andric 113e8d8bef9SDimitry Andricclass uimm<int num, int shift = 0> : Operand<i32>, 114e8d8bef9SDimitry Andric ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> { 115e8d8bef9SDimitry Andric let EncoderMethod = "getImmOpValue<"#shift#">"; 116fe6060f1SDimitry Andric let ParserMatchClass = 117fe6060f1SDimitry Andric !if(!ne(shift, 0), 118fe6060f1SDimitry Andric UImmAsmOperand<num, "Shift"#shift>, 119fe6060f1SDimitry Andric UImmAsmOperand<num>); 120349cc55cSDimitry Andric let DecoderMethod = "decodeUImmOperand<"#num#", "#shift#">"; 121e8d8bef9SDimitry Andric} 122e8d8bef9SDimitry Andric 12306c3fb27SDimitry Andricclass uimm_neg<int num, int shift = 0> : Operand<i32>, 12406c3fb27SDimitry Andric ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(-Imm);"> { 12506c3fb27SDimitry Andric} 12606c3fb27SDimitry Andric 127e8d8bef9SDimitry Andricclass simm<int num, int shift = 0> : Operand<i32>, 128e8d8bef9SDimitry Andric ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> { 129e8d8bef9SDimitry Andric let EncoderMethod = "getImmOpValue<"#shift#">"; 130fe6060f1SDimitry Andric let ParserMatchClass = SImmAsmOperand<num>; 131349cc55cSDimitry Andric let DecoderMethod = "decodeSImmOperand<"#num#", "#shift#">"; 132e8d8bef9SDimitry Andric} 133e8d8bef9SDimitry Andric 134e8d8bef9SDimitry Andricdef nimm_XFORM : SDNodeXForm<imm, [{ 135e8d8bef9SDimitry Andric return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32); 136e8d8bef9SDimitry Andric}]>; 137e8d8bef9SDimitry Andricclass nimm<int num> : Operand<i32>, 138e8d8bef9SDimitry Andric ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> { 139fe6060f1SDimitry Andric let ParserMatchClass = UImmAsmOperand<num>; 140e8d8bef9SDimitry Andric} 141e8d8bef9SDimitry Andric 142fe6060f1SDimitry Andricdef uimm32_hi16 : SDNodeXForm<imm, [{ 143fe6060f1SDimitry Andric return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF, 144fe6060f1SDimitry Andric SDLoc(N), MVT::i32); 145fe6060f1SDimitry Andric}]>; 146349cc55cSDimitry Andricdef uimm32_lo16 : SDNodeXForm<imm, [{ 147349cc55cSDimitry Andric return CurDAG->getTargetConstant(N->getZExtValue()& 0xFFFF, SDLoc(N), MVT::i32); 148349cc55cSDimitry Andric}]>; 149fe6060f1SDimitry Andricdef uimm16_16_xform : Operand<i32>, 150fe6060f1SDimitry Andric ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> { 151fe6060f1SDimitry Andric let ParserMatchClass = UImmAsmOperand<16>; 152349cc55cSDimitry Andric let EncoderMethod = "getImmOpValue"; 153fe6060f1SDimitry Andric} 154fe6060f1SDimitry Andric 155fe6060f1SDimitry Andricdef uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> { 156fe6060f1SDimitry Andric let EncoderMethod = "getImmShiftOpValue"; 157fe6060f1SDimitry Andric let ParserMatchClass = UImmAsmOperand<2>; 158349cc55cSDimitry Andric let DecoderMethod = "decodeImmShiftOpValue"; 159fe6060f1SDimitry Andric} 160fe6060f1SDimitry Andric 161*5f757f3fSDimitry Andric// Optimize (or x, imm) to (BSETI x, log2(imm)). We should exclude the 162*5f757f3fSDimitry Andric// case can be opimized to (ORI32/ORI16 x, imm). 163*5f757f3fSDimitry Andricdef imm32_1_pop_bit_XFORM : SDNodeXForm<imm, [{ 164*5f757f3fSDimitry Andric uint32_t I = N->getZExtValue(); 165*5f757f3fSDimitry Andric return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N), 166*5f757f3fSDimitry Andric N->getValueType(0)); 167*5f757f3fSDimitry Andric}]>; 168*5f757f3fSDimitry Andricdef imm32_1_pop_bit : PatLeaf<(imm), [{ 169*5f757f3fSDimitry Andric uint32_t I = N->getZExtValue(); 170*5f757f3fSDimitry Andric return llvm::popcount(I) == 1 && I > 0xfff; 171*5f757f3fSDimitry Andric}]>; 172*5f757f3fSDimitry Andric 173*5f757f3fSDimitry Andric// Optimize (and x, imm) to (BCLRI x, log2(~imm)). We should exclude the 174*5f757f3fSDimitry Andric// case can be opimized to (ANDNI x, ~imm). 175*5f757f3fSDimitry Andricdef imm32_1_zero_bit_XFORM : SDNodeXForm<imm, [{ 176*5f757f3fSDimitry Andric uint32_t I = ~N->getZExtValue(); 177*5f757f3fSDimitry Andric return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N), 178*5f757f3fSDimitry Andric N->getValueType(0)); 179*5f757f3fSDimitry Andric}]>; 180*5f757f3fSDimitry Andricdef imm32_1_zero_bit : PatLeaf<(imm), [{ 181*5f757f3fSDimitry Andric uint32_t I = ~N->getZExtValue(); 182*5f757f3fSDimitry Andric return llvm::popcount(I) == 1 && I > 0xfff; 183*5f757f3fSDimitry Andric}]>; 184*5f757f3fSDimitry Andric 185fe6060f1SDimitry Andricdef CSKYSymbol : AsmOperandClass { 186fe6060f1SDimitry Andric let Name = "CSKYSymbol"; 187fe6060f1SDimitry Andric let RenderMethod = "addImmOperands"; 188fe6060f1SDimitry Andric let DiagnosticType = "InvalidCSKYSymbol"; 189fe6060f1SDimitry Andric let ParserMethod = "parseCSKYSymbol"; 190fe6060f1SDimitry Andric} 191fe6060f1SDimitry Andric 192753f127fSDimitry Andricdef br_symbol : Operand<OtherVT> { 193fe6060f1SDimitry Andric let EncoderMethod = 194fe6060f1SDimitry Andric "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>"; 195fe6060f1SDimitry Andric let ParserMatchClass = CSKYSymbol; 196349cc55cSDimitry Andric let DecoderMethod = "decodeSImmOperand<16, 1>"; 197349cc55cSDimitry Andric let PrintMethod = "printCSKYSymbolOperand"; 198349cc55cSDimitry Andric let OperandType = "OPERAND_PCREL"; 199fe6060f1SDimitry Andric} 200fe6060f1SDimitry Andric 201fe6060f1SDimitry Andricdef call_symbol : Operand<iPTR> { 202fe6060f1SDimitry Andric let ParserMatchClass = CSKYSymbol; 203fe6060f1SDimitry Andric let EncoderMethod = "getCallSymbolOpValue"; 204349cc55cSDimitry Andric let DecoderMethod = "decodeSImmOperand<26, 1>"; 205349cc55cSDimitry Andric let PrintMethod = "printCSKYSymbolOperand"; 206349cc55cSDimitry Andric let OperandType = "OPERAND_PCREL"; 207fe6060f1SDimitry Andric} 208fe6060f1SDimitry Andric 209fe6060f1SDimitry Andricdef Constpool : AsmOperandClass { 210349cc55cSDimitry Andric let Name = "Constpool"; 211349cc55cSDimitry Andric let RenderMethod = "addConstpoolOperands"; 212fe6060f1SDimitry Andric let DiagnosticType = "InvalidConstpool"; 213fe6060f1SDimitry Andric let ParserMethod = "parseConstpoolSymbol"; 214fe6060f1SDimitry Andric} 215fe6060f1SDimitry Andric 216fe6060f1SDimitry Andricdef constpool_symbol : Operand<iPTR> { 217fe6060f1SDimitry Andric let ParserMatchClass = Constpool; 218fe6060f1SDimitry Andric let EncoderMethod = 219fe6060f1SDimitry Andric "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>"; 220349cc55cSDimitry Andric let DecoderMethod = "decodeUImmOperand<16, 2>"; 221349cc55cSDimitry Andric let PrintMethod = "printConstpool"; 222349cc55cSDimitry Andric let OperandType = "OPERAND_PCREL"; 223349cc55cSDimitry Andric} 224349cc55cSDimitry Andric 225349cc55cSDimitry Andricdef DataAsmClass : AsmOperandClass { 226349cc55cSDimitry Andric let Name = "DataSymbol"; 227349cc55cSDimitry Andric let RenderMethod = "addConstpoolOperands"; 228349cc55cSDimitry Andric let DiagnosticType = "InvalidConstpool"; 229349cc55cSDimitry Andric let ParserMethod = "parseDataSymbol"; 230349cc55cSDimitry Andric} 231349cc55cSDimitry Andric 232349cc55cSDimitry Andricclass data_symbol<string reloc, int shift> : Operand<iPTR> { 233349cc55cSDimitry Andric let ParserMatchClass = Constpool; 234349cc55cSDimitry Andric let EncoderMethod = 235349cc55cSDimitry Andric "getDataSymbolOpValue<"#reloc#">"; 236349cc55cSDimitry Andric let DecoderMethod = "decodeUImmOperand<18, "#shift#">"; 237349cc55cSDimitry Andric let PrintMethod = "printDataSymbol"; 238fe6060f1SDimitry Andric} 239fe6060f1SDimitry Andric 240fe6060f1SDimitry Andricdef bare_symbol : Operand<iPTR> { 241fe6060f1SDimitry Andric let ParserMatchClass = CSKYSymbol; 242fe6060f1SDimitry Andric let EncoderMethod = "getBareSymbolOpValue"; 243349cc55cSDimitry Andric let PrintMethod = "printCSKYSymbolOperand"; 244349cc55cSDimitry Andric let DecoderMethod = "decodeSImmOperand<18, 1>"; 245349cc55cSDimitry Andric let OperandType = "OPERAND_PCREL"; 246fe6060f1SDimitry Andric} 247e8d8bef9SDimitry Andric 2480eae32dcSDimitry Andricdef oimm3 : oimm<3> { 2490eae32dcSDimitry Andric let MCOperandPredicate = [{ 2500eae32dcSDimitry Andric int64_t Imm; 2510eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 2520eae32dcSDimitry Andric return isUInt<3>(Imm - 1); 2530eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 2540eae32dcSDimitry Andric }]; 2550eae32dcSDimitry Andric} 256349cc55cSDimitry Andricdef oimm4 : oimm<4>; 2570eae32dcSDimitry Andricdef oimm5 : oimm<5> { 2580eae32dcSDimitry Andric let MCOperandPredicate = [{ 2590eae32dcSDimitry Andric int64_t Imm; 2600eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 2610eae32dcSDimitry Andric return isUInt<5>(Imm - 1); 2620eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 2630eae32dcSDimitry Andric }]; 2640eae32dcSDimitry Andric} 265349cc55cSDimitry Andricdef oimm6 : oimm<6>; 266349cc55cSDimitry Andric 267349cc55cSDimitry Andricdef imm5_idly : Operand<i32>, ImmLeaf<i32, 268349cc55cSDimitry Andric "return Imm <= 32 && Imm >= 0;"> { 269349cc55cSDimitry Andric let EncoderMethod = "getImmOpValueIDLY"; 270349cc55cSDimitry Andric let DecoderMethod = "decodeOImmOperand<5>"; 271349cc55cSDimitry Andric} 272349cc55cSDimitry Andric 2730eae32dcSDimitry Andricdef oimm8 : oimm<8> { 2740eae32dcSDimitry Andric let MCOperandPredicate = [{ 2750eae32dcSDimitry Andric int64_t Imm; 2760eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 2770eae32dcSDimitry Andric return isUInt<8>(Imm - 1); 2780eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 2790eae32dcSDimitry Andric }]; 2800eae32dcSDimitry Andric} 2810eae32dcSDimitry Andricdef oimm12 : oimm<12> { 2820eae32dcSDimitry Andric let MCOperandPredicate = [{ 2830eae32dcSDimitry Andric int64_t Imm; 2840eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 2850eae32dcSDimitry Andric return isUInt<12>(Imm - 1); 2860eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 2870eae32dcSDimitry Andric }]; 2880eae32dcSDimitry Andric} 2890eae32dcSDimitry Andricdef oimm16 : oimm<16> { 2900eae32dcSDimitry Andric let MCOperandPredicate = [{ 2910eae32dcSDimitry Andric int64_t Imm; 2920eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 2930eae32dcSDimitry Andric return isUInt<16>(Imm - 1); 2940eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 2950eae32dcSDimitry Andric }]; 2960eae32dcSDimitry Andric} 297e8d8bef9SDimitry Andric 29806c3fb27SDimitry Andricdef oimm8_neg : oimm_neg<8> { 29906c3fb27SDimitry Andric let MCOperandPredicate = [{ 30006c3fb27SDimitry Andric int64_t Imm; 30106c3fb27SDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 30206c3fb27SDimitry Andric return isUInt<8>(-Imm - 1); 30306c3fb27SDimitry Andric return MCOp.isBareSymbolRef(); 30406c3fb27SDimitry Andric }]; 30506c3fb27SDimitry Andric} 30606c3fb27SDimitry Andricdef oimm12_neg : oimm_neg<12> { 30706c3fb27SDimitry Andric let MCOperandPredicate = [{ 30806c3fb27SDimitry Andric int64_t Imm; 30906c3fb27SDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 31006c3fb27SDimitry Andric return isUInt<12>(-Imm - 1); 31106c3fb27SDimitry Andric return MCOp.isBareSymbolRef(); 31206c3fb27SDimitry Andric }]; 31306c3fb27SDimitry Andric} 31406c3fb27SDimitry Andric 315e8d8bef9SDimitry Andricdef nimm12 : nimm<12>; 316e8d8bef9SDimitry Andric 317349cc55cSDimitry Andricdef uimm1 : uimm<1>; 318349cc55cSDimitry Andricdef uimm2 : uimm<2>; 319349cc55cSDimitry Andric 320349cc55cSDimitry Andric 321349cc55cSDimitry Andricdef uimm2_jmpix : Operand<i32>, 322349cc55cSDimitry Andric ImmLeaf<i32, "return Imm == 16 || Imm == 24 || Imm == 32 || Imm == 40;"> { 323349cc55cSDimitry Andric let EncoderMethod = "getImmJMPIX"; 324349cc55cSDimitry Andric let DecoderMethod = "decodeJMPIXImmOperand"; 325349cc55cSDimitry Andric} 326349cc55cSDimitry Andric 327349cc55cSDimitry Andricdef uimm3 : uimm<3>; 328349cc55cSDimitry Andricdef uimm4 : uimm<4>; 3290eae32dcSDimitry Andricdef uimm5 : uimm<5> { 3300eae32dcSDimitry Andric let MCOperandPredicate = [{ 3310eae32dcSDimitry Andric int64_t Imm; 3320eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 3330eae32dcSDimitry Andric return isShiftedUInt<5, 0>(Imm); 3340eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 3350eae32dcSDimitry Andric }]; 3360eae32dcSDimitry Andric} 337349cc55cSDimitry Andricdef uimm5_msb_size : uimm<5> { 338349cc55cSDimitry Andric let EncoderMethod = "getImmOpValueMSBSize"; 339349cc55cSDimitry Andric} 340349cc55cSDimitry Andric 3410eae32dcSDimitry Andricdef uimm5_1 : uimm<5, 1> { 3420eae32dcSDimitry Andric let MCOperandPredicate = [{ 3430eae32dcSDimitry Andric int64_t Imm; 3440eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 3450eae32dcSDimitry Andric return isShiftedUInt<5, 1>(Imm); 3460eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 3470eae32dcSDimitry Andric }]; 3480eae32dcSDimitry Andric} 3490eae32dcSDimitry Andricdef uimm5_2 : uimm<5, 2> { 3500eae32dcSDimitry Andric let MCOperandPredicate = [{ 3510eae32dcSDimitry Andric int64_t Imm; 3520eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 3530eae32dcSDimitry Andric return isShiftedUInt<5, 2>(Imm); 3540eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 3550eae32dcSDimitry Andric }]; 3560eae32dcSDimitry Andric} 357349cc55cSDimitry Andricdef uimm6 : uimm<6>; 358349cc55cSDimitry Andricdef uimm7 : uimm<7>; 359349cc55cSDimitry Andricdef uimm7_1 : uimm<7, 1>; 3600eae32dcSDimitry Andricdef uimm7_2 : uimm<7, 2>{ 3610eae32dcSDimitry Andric let MCOperandPredicate = [{ 3620eae32dcSDimitry Andric int64_t Imm; 3630eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 3640eae32dcSDimitry Andric return isShiftedUInt<7, 2>(Imm); 3650eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 3660eae32dcSDimitry Andric }]; 3670eae32dcSDimitry Andric} 368349cc55cSDimitry Andricdef uimm7_3 : uimm<7, 3>; 3690eae32dcSDimitry Andricdef uimm8 : uimm<8> { 3700eae32dcSDimitry Andric let MCOperandPredicate = [{ 3710eae32dcSDimitry Andric int64_t Imm; 3720eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 3730eae32dcSDimitry Andric return isShiftedUInt<8, 0>(Imm); 3740eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 3750eae32dcSDimitry Andric }]; 3760eae32dcSDimitry Andric} 3770eae32dcSDimitry Andricdef uimm8_2 : uimm<8, 2> { 3780eae32dcSDimitry Andric let MCOperandPredicate = [{ 3790eae32dcSDimitry Andric int64_t Imm; 3800eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 3810eae32dcSDimitry Andric return isShiftedUInt<8, 2>(Imm); 3820eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 3830eae32dcSDimitry Andric }]; 3840eae32dcSDimitry Andric} 385349cc55cSDimitry Andricdef uimm8_3 : uimm<8, 3>; 386349cc55cSDimitry Andricdef uimm8_8 : uimm<8, 8>; 387349cc55cSDimitry Andricdef uimm8_16 : uimm<8, 16>; 388349cc55cSDimitry Andricdef uimm8_24 : uimm<8, 24>; 3890eae32dcSDimitry Andricdef uimm12 : uimm<12> { 3900eae32dcSDimitry Andric let MCOperandPredicate = [{ 3910eae32dcSDimitry Andric int64_t Imm; 3920eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 3930eae32dcSDimitry Andric return isShiftedUInt<12, 0>(Imm); 3940eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 3950eae32dcSDimitry Andric }]; 3960eae32dcSDimitry Andric} 3970eae32dcSDimitry Andricdef uimm12_1 : uimm<12, 1> { 3980eae32dcSDimitry Andric let MCOperandPredicate = [{ 3990eae32dcSDimitry Andric int64_t Imm; 4000eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 4010eae32dcSDimitry Andric return isShiftedUInt<12, 1>(Imm); 4020eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 4030eae32dcSDimitry Andric }]; 4040eae32dcSDimitry Andric} 4050eae32dcSDimitry Andricdef uimm12_2 : uimm<12, 2> { 4060eae32dcSDimitry Andric let MCOperandPredicate = [{ 4070eae32dcSDimitry Andric int64_t Imm; 4080eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 4090eae32dcSDimitry Andric return isShiftedUInt<12, 2>(Imm); 4100eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 4110eae32dcSDimitry Andric }]; 4120eae32dcSDimitry Andric} 4130eae32dcSDimitry Andricdef uimm16 : uimm<16> { 4140eae32dcSDimitry Andric let MCOperandPredicate = [{ 4150eae32dcSDimitry Andric int64_t Imm; 4160eae32dcSDimitry Andric if (MCOp.evaluateAsConstantImm(Imm)) 4170eae32dcSDimitry Andric return isShiftedUInt<16, 0>(Imm); 4180eae32dcSDimitry Andric return MCOp.isBareSymbolRef(); 4190eae32dcSDimitry Andric }]; 4200eae32dcSDimitry Andric} 421349cc55cSDimitry Andricdef uimm16_8 : uimm<16, 8>; 422349cc55cSDimitry Andricdef uimm16_16 : uimm<16, 16>; 423349cc55cSDimitry Andricdef uimm20 : uimm<20>; 424349cc55cSDimitry Andricdef uimm24 : uimm<24>; 425349cc55cSDimitry Andricdef uimm24_8 : uimm<24, 8>; 426fe6060f1SDimitry Andric 42706c3fb27SDimitry Andricdef uimm5_neg : uimm_neg<5>; 42806c3fb27SDimitry Andric 429349cc55cSDimitry Andricdef simm8_2 : simm<8, 2>; 430349cc55cSDimitry Andric 431349cc55cSDimitry Andricclass RegSeqAsmOperand<string Suffix = ""> : AsmOperandClass { 432349cc55cSDimitry Andric let Name = "RegSeq"#Suffix; 433349cc55cSDimitry Andric let RenderMethod = "addRegSeqOperands"; 434349cc55cSDimitry Andric let DiagnosticType = "InvalidRegSeq"; 435349cc55cSDimitry Andric let ParserMethod = "parseRegSeq"; 436349cc55cSDimitry Andric} 437349cc55cSDimitry Andric 438349cc55cSDimitry Andricdef regseq : Operand<iPTR> { 439349cc55cSDimitry Andric let EncoderMethod = "getRegisterSeqOpValue"; 440349cc55cSDimitry Andric let ParserMatchClass = RegSeqAsmOperand<"">; 441349cc55cSDimitry Andric let PrintMethod = "printRegisterSeq"; 442349cc55cSDimitry Andric let DecoderMethod = "DecodeRegSeqOperand"; 443349cc55cSDimitry Andric let MIOperandInfo = (ops GPR, uimm5); 444349cc55cSDimitry Andric} 445349cc55cSDimitry Andric 446349cc55cSDimitry Andricdef RegListAsmOperand : AsmOperandClass { 447349cc55cSDimitry Andric let Name = "RegList"; 448349cc55cSDimitry Andric let RenderMethod = "addRegListOperands"; 449349cc55cSDimitry Andric let DiagnosticType = "InvalidRegList"; 450349cc55cSDimitry Andric let ParserMethod = "parseRegList"; 451349cc55cSDimitry Andric} 452349cc55cSDimitry Andric 453349cc55cSDimitry Andricdef reglist : Operand<iPTR> { 454349cc55cSDimitry Andric let ParserMatchClass = RegListAsmOperand; 455349cc55cSDimitry Andric let PrintMethod = "printRegisterList"; 456349cc55cSDimitry Andric} 457349cc55cSDimitry Andric 458349cc55cSDimitry Andricdef PSRFlag : AsmOperandClass { 459349cc55cSDimitry Andric let Name = "PSRFlag"; 460349cc55cSDimitry Andric let RenderMethod = "addImmOperands"; 461349cc55cSDimitry Andric let DiagnosticType = "InvalidPSRFlag"; 462349cc55cSDimitry Andric let ParserMethod = "parsePSRFlag"; 463349cc55cSDimitry Andric} 464349cc55cSDimitry Andric 465349cc55cSDimitry Andricdef psrflag : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<5, 0>(Imm);"> { 466349cc55cSDimitry Andric let EncoderMethod = "getImmOpValue"; 467349cc55cSDimitry Andric let ParserMatchClass = PSRFlag; 468349cc55cSDimitry Andric let PrintMethod = "printPSRFlag"; 469349cc55cSDimitry Andric} 470fe6060f1SDimitry Andric 47181ad6265SDimitry Andricmulticlass uimm8SRLXForm<SDNode opc> { 47281ad6265SDimitry Andric def _0: SDNodeXForm<opc, 47381ad6265SDimitry Andric [{return CurDAG->getTargetConstant((N->getZExtValue() >> 0) & 0xFF, SDLoc(N), MVT::i32);}]>; 47481ad6265SDimitry Andric def _8: SDNodeXForm<opc, 47581ad6265SDimitry Andric [{return CurDAG->getTargetConstant((N->getZExtValue() >> 8) & 0xFF, SDLoc(N), MVT::i32);}]>; 47681ad6265SDimitry Andric def _16: SDNodeXForm<opc, 47781ad6265SDimitry Andric [{return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFF, SDLoc(N), MVT::i32);}]>; 47881ad6265SDimitry Andric def _24: SDNodeXForm<opc, 47981ad6265SDimitry Andric [{return CurDAG->getTargetConstant((N->getZExtValue() >> 24) & 0xFF, SDLoc(N), MVT::i32);}]>; 48081ad6265SDimitry Andric} 48181ad6265SDimitry Andric 48281ad6265SDimitry Andricdefm uimm8SRL : uimm8SRLXForm<imm>; 48381ad6265SDimitry Andric 484fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 485fe6060f1SDimitry Andric// Instruction Formats 486fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 487fe6060f1SDimitry Andric 488fe6060f1SDimitry Andricinclude "CSKYInstrFormats.td" 489e8d8bef9SDimitry Andric 490e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 491e8d8bef9SDimitry Andric// Instruction definitions. 492e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 493e8d8bef9SDimitry Andric 494e8d8bef9SDimitry Andricclass TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>; 495e8d8bef9SDimitry Andricclass BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 496e8d8bef9SDimitry Andricclass UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>; 497e8d8bef9SDimitry Andric 498349cc55cSDimitry Andricdef eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{ 499349cc55cSDimitry Andric return isOrEquivalentToAdd(N); 500349cc55cSDimitry Andric}]>; 501349cc55cSDimitry Andric 502349cc55cSDimitry Andricdef BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">; 503349cc55cSDimitry Andric 504349cc55cSDimitry Andric 505349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 506349cc55cSDimitry Andric// CSKYPseudo 507349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 508349cc55cSDimitry Andric 509349cc55cSDimitry Andric// Pessimistically assume the stack pointer will be clobbered 510349cc55cSDimitry Andriclet Defs = [R14], Uses = [R14] in { 511349cc55cSDimitry Andricdef ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 512349cc55cSDimitry Andric "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>; 513349cc55cSDimitry Andricdef ADJCALLSTACKUP : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 514349cc55cSDimitry Andric "!ADJCALLSTACKUP $amt1, $amt2", [(callseq_end timm:$amt1, timm:$amt2)]>; 515349cc55cSDimitry Andric} // Defs = [R14], Uses = [R14] 516fe6060f1SDimitry Andric 517fe6060f1SDimitry Andric 518fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 519fe6060f1SDimitry Andric// Basic ALU instructions. 520fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 521fe6060f1SDimitry Andric 522349cc55cSDimitry Andriclet Predicates = [iHasE2] in { 523349cc55cSDimitry Andric let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 524349cc55cSDimitry Andric let isAdd = 1 in 525e8d8bef9SDimitry Andric def ADDI32 : I_12<0x0, "addi32", add, oimm12>; 526e8d8bef9SDimitry Andric def SUBI32 : I_12<0x1, "subi32", sub, oimm12>; 527fe6060f1SDimitry Andric def ORI32 : I_16_ZX<"ori32", uimm16, 528fe6060f1SDimitry Andric [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>; 529fe6060f1SDimitry Andric def XORI32 : I_12<0x4, "xori32", xor, uimm12>; 530e8d8bef9SDimitry Andric def ANDI32 : I_12<0x2, "andi32", and, uimm12>; 531e8d8bef9SDimitry Andric def ANDNI32 : I_12<0x3, "andni32", and, nimm12>; 532e8d8bef9SDimitry Andric def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32", 533e8d8bef9SDimitry Andric (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 534e8d8bef9SDimitry Andric [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>; 535e8d8bef9SDimitry Andric def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32", 536e8d8bef9SDimitry Andric (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 537e8d8bef9SDimitry Andric [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>; 538e8d8bef9SDimitry Andric def ASRI32 : I_5_XZ<0x12, 0x4, "asri32", 539e8d8bef9SDimitry Andric (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 540e8d8bef9SDimitry Andric [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>; 541fe6060f1SDimitry Andric def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32", 542fe6060f1SDimitry Andric (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), 543fe6060f1SDimitry Andric [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>; 544e8d8bef9SDimitry Andric 545349cc55cSDimitry Andric def ROTRI32 : CSKYPseudo<(outs GPR:$rz), (ins GPR:$rx, oimm5:$imm5), 546349cc55cSDimitry Andric "rotri32 $rz, $rx, $imm5", []>; 547349cc55cSDimitry Andric } 548349cc55cSDimitry Andric let isAdd = 1 in 549e8d8bef9SDimitry Andric def ADDU32 : R_YXZ_SP_F1<0x0, 0x1, 550e8d8bef9SDimitry Andric BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>; 551e8d8bef9SDimitry Andric def SUBU32 : R_YXZ_SP_F1<0x0, 0x4, 552e8d8bef9SDimitry Andric BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">; 553349cc55cSDimitry Andric 554fe6060f1SDimitry Andric def MULT32 : R_YXZ_SP_F1<0x21, 0x1, 555fe6060f1SDimitry Andric BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>; 556e8d8bef9SDimitry Andric def AND32 : R_YXZ_SP_F1<0x8, 0x1, 557e8d8bef9SDimitry Andric BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>; 558e8d8bef9SDimitry Andric def ANDN32 : R_YXZ_SP_F1<0x8, 0x2, 559e8d8bef9SDimitry Andric BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">; 560e8d8bef9SDimitry Andric def OR32: R_YXZ_SP_F1<0x9, 0x1, 561e8d8bef9SDimitry Andric BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>; 562e8d8bef9SDimitry Andric def XOR32 : R_YXZ_SP_F1<0x9, 0x2, 563e8d8bef9SDimitry Andric BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>; 564e8d8bef9SDimitry Andric def NOR32 : R_YXZ_SP_F1<0x9, 0x4, 565e8d8bef9SDimitry Andric BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>; 566349cc55cSDimitry Andric let isCodeGenOnly = 1 in 567fe6060f1SDimitry Andric def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx), 568fe6060f1SDimitry Andric "not32", [(set GPR:$rz, (not GPR:$rx))]>; 569349cc55cSDimitry Andric 570349cc55cSDimitry Andric let Size = 8 in 571349cc55cSDimitry Andric def NEG32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx), "neg32 $rd, $rx", []>; 572349cc55cSDimitry Andric 573349cc55cSDimitry Andric let Size = 8 in 574349cc55cSDimitry Andric def RSUBI32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx, uimm12:$imm12), "rsubi32 $rd, $rx, $imm12", []>; 575349cc55cSDimitry Andric 57606c3fb27SDimitry Andric def : Pat<(add GPR:$rs1, (oimm12_neg:$im)), 57706c3fb27SDimitry Andric (SUBI32 GPR:$rs1, (imm_neg_XFORM oimm12_neg:$im))>; 57806c3fb27SDimitry Andric 579e8d8bef9SDimitry Andric def LSL32 : R_YXZ_SP_F1<0x10, 0x1, 580e8d8bef9SDimitry Andric BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">; 581e8d8bef9SDimitry Andric def LSR32 : R_YXZ_SP_F1<0x10, 0x2, 582e8d8bef9SDimitry Andric BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">; 583e8d8bef9SDimitry Andric def ASR32 : R_YXZ_SP_F1<0x10, 0x4, 584e8d8bef9SDimitry Andric BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">; 585fe6060f1SDimitry Andric def ROTL32 : R_YXZ_SP_F1<0x10, 0x8, 586fe6060f1SDimitry Andric BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">; 587fe6060f1SDimitry Andric 588349cc55cSDimitry Andric def BMASKI32 : I_5_Z<0b010100, 0x1, "bmaski32", oimm5, []>; 589349cc55cSDimitry Andric def LSLC32 : I_5_XZ<0x13, 0x1, "lslc32", 590349cc55cSDimitry Andric (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>; 591349cc55cSDimitry Andric def LSRC32 : I_5_XZ<0x13, 0x2, "lsrc32", 592349cc55cSDimitry Andric (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>; 593349cc55cSDimitry Andric def ASRC32 : I_5_XZ<0x13, 0x4, "asrc32", 594349cc55cSDimitry Andric (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>; 595349cc55cSDimitry Andric def XSR32 : I_5_XZ<0x13, 0x8, "xsr32", 596349cc55cSDimitry Andric (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5, CARRY:$cin), []>; 597fe6060f1SDimitry Andric 598fe6060f1SDimitry Andric def IXH32 : R_YXZ_SP_F1<0x2, 0x1, 599fe6060f1SDimitry Andric BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">; 600fe6060f1SDimitry Andric def IXW32 : R_YXZ_SP_F1<0x2, 0x2, 601fe6060f1SDimitry Andric BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">; 602349cc55cSDimitry Andric let Predicates = [iHas2E3] in 603fe6060f1SDimitry Andric def IXD32 : R_YXZ_SP_F1<0x2, 0x4, 604fe6060f1SDimitry Andric BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">; 605fe6060f1SDimitry Andric 606349cc55cSDimitry Andric let isCommutable = 1, isAdd = 1 in 607fe6060f1SDimitry Andric def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout), 608fe6060f1SDimitry Andric (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>; 609fe6060f1SDimitry Andric def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout), 610fe6060f1SDimitry Andric (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>; 611fe6060f1SDimitry Andric 612349cc55cSDimitry Andric def INCF32 : I_5_ZX<0x3, 0x1, "incf32", uimm5, []>; 613349cc55cSDimitry Andric def INCT32 : I_5_ZX<0x3, 0x2, "inct32", uimm5, []>; 614349cc55cSDimitry Andric def DECF32 : I_5_ZX<0x3, 0x4, "decf32", uimm5, []>; 615349cc55cSDimitry Andric def DECT32 : I_5_ZX<0x3, 0x8, "dect32", uimm5, []>; 616349cc55cSDimitry Andric} 617349cc55cSDimitry Andric 618349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 619e8d8bef9SDimitry Andric def DIVS32 : R_YXZ_SP_F1<0x20, 0x2, 620e8d8bef9SDimitry Andric BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">; 621e8d8bef9SDimitry Andric def DIVU32 : R_YXZ_SP_F1<0x20, 0x1, 622e8d8bef9SDimitry Andric BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">; 623e8d8bef9SDimitry Andric 624fe6060f1SDimitry Andric def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32", 625fe6060f1SDimitry Andric (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; 626fe6060f1SDimitry Andric def DECLT32 : I_5_XZ<0x4, 0x2, "declt32", 627fe6060f1SDimitry Andric (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; 628fe6060f1SDimitry Andric def DECNE32 : I_5_XZ<0x4, 0x4, "decne32", 629fe6060f1SDimitry Andric (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; 630fe6060f1SDimitry Andric 631349cc55cSDimitry Andric def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>; 632349cc55cSDimitry Andric let isCodeGenOnly = 1 in { 633349cc55cSDimitry Andric def SEXTB32 : I_5_XZ_US<0x16, 0, 7, "sextb32", sext_inreg, i8>; 634349cc55cSDimitry Andric def SEXTH32 : I_5_XZ_US<0x16, 0, 15, "sexth32", sext_inreg, i16>; 635349cc55cSDimitry Andric def ZEXTB32 : I_5_XZ_UZ<0x15, 0, 7, "zextb32", 255>; 636349cc55cSDimitry Andric def ZEXTH32 : I_5_XZ_UZ<0x15, 0, 15, "zexth32", 65535>; 637349cc55cSDimitry Andric } 638349cc55cSDimitry Andric def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>; 639349cc55cSDimitry Andric 640349cc55cSDimitry Andric let Constraints = "$rZ = $rz" in 641349cc55cSDimitry Andric def INS32 : I_5_XZ_INS<0b010111, (outs GPR:$rz), (ins GPR:$rZ, GPR:$rx, uimm5_msb_size:$msb, uimm5:$lsb), "ins32", []>; 642349cc55cSDimitry Andric} 643349cc55cSDimitry Andric 644349cc55cSDimitry Andriclet Predicates = [iHas3E3r1] in { 645349cc55cSDimitry Andricdef MULTS32 : R_YXZ<0x3e, 0x20, 0x10, (outs GPRPair:$rz), 646349cc55cSDimitry Andric (ins GPR:$rx, GPR:$ry), "mul.s32", []>; 647349cc55cSDimitry Andricdef MULTU32 : R_YXZ<0x3e, 0x20, 0x00, (outs GPRPair:$rz), 648349cc55cSDimitry Andric (ins GPR:$rx, GPR:$ry), "mul.u32", []>; 649349cc55cSDimitry Andric 650349cc55cSDimitry Andriclet Constraints = "$rZ = $rz" in { 651349cc55cSDimitry Andricdef MULATS32 : R_YXZ<0x3e, 0x20, 0x14, (outs GPRPair:$rZ), 652349cc55cSDimitry Andric (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.s32", []>; 653349cc55cSDimitry Andricdef MULATU32 : R_YXZ<0x3e, 0x20, 0x04, (outs GPRPair:$rZ), 654349cc55cSDimitry Andric (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.u32", []>; 655349cc55cSDimitry Andric} 656349cc55cSDimitry Andric} 657349cc55cSDimitry Andric 658349cc55cSDimitry Andricdef MULSH32 : R_YXZ<0x31, 0b100100, 0b00001, (outs GPR:$rz), 659349cc55cSDimitry Andric (ins GPR:$rx, GPR:$ry), "mulsh32", []>; 660fe6060f1SDimitry Andric 661fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 662fe6060f1SDimitry Andric// Load & Store instructions. 663fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 664fe6060f1SDimitry Andric 665fe6060f1SDimitry Andricdef LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>; 666fe6060f1SDimitry Andricdef LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>; 667fe6060f1SDimitry Andricdef LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>; 668fe6060f1SDimitry Andric 669349cc55cSDimitry Andriclet OutOperandList = (outs GPRPair:$rz) in 670349cc55cSDimitry Andricdef LD32D : I_LD<AddrMode32WD, 0x3, "ld32.d", uimm12_2>; 671fe6060f1SDimitry Andric 672349cc55cSDimitry Andriclet Predicates = [iHasE2] in { 673fe6060f1SDimitry Andric def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>; 674fe6060f1SDimitry Andric def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>; 675fe6060f1SDimitry Andric 676349cc55cSDimitry Andric def LDM32 : I_5_YX<0b110100, 0b000111, 677349cc55cSDimitry Andric (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "ldm32\t$regs, (${rx})", []>; 678349cc55cSDimitry Andric def STM32 : I_5_YX<0b110101, 0b000111, 679349cc55cSDimitry Andric (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "stm32\t$regs, (${rx})", []>; 680fe6060f1SDimitry Andric 681349cc55cSDimitry Andric let Size = 4, isCodeGenOnly = 0 in { 682349cc55cSDimitry Andric def LDQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops), 683349cc55cSDimitry Andric "ldq32\t$regs, (${rx})", []>; 684349cc55cSDimitry Andric def STQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops), 685349cc55cSDimitry Andric "stq32\t$regs, (${rx})", []>; 686349cc55cSDimitry Andric } 687349cc55cSDimitry Andric 688349cc55cSDimitry Andric} 689fe6060f1SDimitry Andric 690fe6060f1SDimitry Andricdef ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>; 691fe6060f1SDimitry Andricdef ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>; 692fe6060f1SDimitry Andricdef ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>; 693fe6060f1SDimitry Andric 694349cc55cSDimitry Andriclet InOperandList = (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm12 ) in 695349cc55cSDimitry Andricdef ST32D : I_ST<AddrMode32WD, 0x3, "st32.d", uimm12_2>; 696fe6060f1SDimitry Andric 697349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 698fe6060f1SDimitry Andric def LDR32B : I_LDR<0x0, "ldr32.b">; 699fe6060f1SDimitry Andric def LDR32BS : I_LDR<0x4, "ldr32.bs">; 700fe6060f1SDimitry Andric def LDR32H : I_LDR<0x1, "ldr32.h">; 701fe6060f1SDimitry Andric def LDR32HS : I_LDR<0x5, "ldr32.hs">; 702fe6060f1SDimitry Andric def LDR32W : I_LDR<0x2, "ldr32.w">; 703fe6060f1SDimitry Andric def STR32B : I_STR<0x0, "str32.b">; 704fe6060f1SDimitry Andric def STR32H : I_STR<0x1, "str32.h">; 705fe6060f1SDimitry Andric def STR32W : I_STR<0x2, "str32.w">; 706349cc55cSDimitry Andric} 707fe6060f1SDimitry Andric 708349cc55cSDimitry Andric// Indicate that we're dumping the CR register, so we'll need to 709349cc55cSDimitry Andric// scavenge a register for it. 710349cc55cSDimitry Andriclet mayStore = 1 in { 711349cc55cSDimitry Andricdef SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm), 712349cc55cSDimitry Andric "!SPILL_CARRY $cond, $rx, $imm", []>; 713349cc55cSDimitry Andric} 714349cc55cSDimitry Andric 715349cc55cSDimitry Andric// Indicate that we're restoring the CR register (previously 716349cc55cSDimitry Andric// spilled), so we'll need to scavenge a register for it. 717349cc55cSDimitry Andriclet mayLoad = 1 in { 718349cc55cSDimitry Andricdef RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm), 719349cc55cSDimitry Andric "!RESTORE_CARRY $cond, $rx, $imm", []>; 720349cc55cSDimitry Andric} 721349cc55cSDimitry Andric 722349cc55cSDimitry Andriclet mayLoad = 1 in { 723349cc55cSDimitry Andricdef STORE_PAIR : CSKYPseudo<(outs), (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm), 724349cc55cSDimitry Andric "!STORE_PAIR $rz, $rx, $imm", []>; 725349cc55cSDimitry Andric} 726349cc55cSDimitry Andric 727349cc55cSDimitry Andriclet mayLoad = 1 in { 728349cc55cSDimitry Andricdef LOAD_PAIR : CSKYPseudo<(outs GPRPair:$rz), (ins GPR:$rx, uimm12_2:$imm), 729349cc55cSDimitry Andric "!LOAD_PAIR $rz, $rx, $imm", []>; 730349cc55cSDimitry Andric} 731fe6060f1SDimitry Andric 732fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 733fe6060f1SDimitry Andric// Compare instructions. 734fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 735349cc55cSDimitry Andriclet Predicates = [iHasE2] in { 736fe6060f1SDimitry Andric def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>; 737fe6060f1SDimitry Andric def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>; 738fe6060f1SDimitry Andric def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>; 739349cc55cSDimitry Andric def CMPLEI32 : CSKYPseudo<(outs CARRY:$ca), (ins GPR:$rx, uimm16:$imm16), 740349cc55cSDimitry Andric "cmplei32\t$rx, $imm16", []>; 741349cc55cSDimitry Andric} 742349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 743fe6060f1SDimitry Andric def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">; 744fe6060f1SDimitry Andric def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">; 745fe6060f1SDimitry Andric def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">; 746fe6060f1SDimitry Andric 747349cc55cSDimitry Andric def SETC32 : CSKY32Inst<AddrModeNone, 0x31, 748349cc55cSDimitry Andric (outs CARRY:$ca), (ins), "setc32", []> { 749349cc55cSDimitry Andric let Inst{25 - 21} = 0; //rx 750349cc55cSDimitry Andric let Inst{20 - 16} = 0; //ry 751349cc55cSDimitry Andric let Inst{15 - 10} = 0x1; 752349cc55cSDimitry Andric let Inst{9 - 5} = 0x1; 753349cc55cSDimitry Andric let Inst{4 - 0} = 0; 754349cc55cSDimitry Andric let isCompare = 1; 755349cc55cSDimitry Andric } 756349cc55cSDimitry Andric def CLRC32 : CSKY32Inst<AddrModeNone, 0x31, 757349cc55cSDimitry Andric (outs CARRY:$ca), (ins), "clrc32", []> { 758349cc55cSDimitry Andric let Inst{25 - 21} = 0; //rx 759349cc55cSDimitry Andric let Inst{20 - 16} = 0; //ry 760349cc55cSDimitry Andric let Inst{15 - 10} = 0x1; 761349cc55cSDimitry Andric let Inst{9 - 5} = 0x4; 762349cc55cSDimitry Andric let Inst{4 - 0} = 0; 763349cc55cSDimitry Andric let isCompare = 1; 764349cc55cSDimitry Andric } 765349cc55cSDimitry Andric 766349cc55cSDimitry Andric def TST32 : R_YX<0x8, 0x4, "tst32">; 767349cc55cSDimitry Andric def TSTNBZ32 : R_X<0x8, 0x8, 768349cc55cSDimitry Andric (outs CARRY:$ca), (ins GPR:$rx), "tstnbz32", []>; 769349cc55cSDimitry Andric} 770fe6060f1SDimitry Andric 771fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 772fe6060f1SDimitry Andric// Data move instructions. 773fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 774fe6060f1SDimitry Andric 775349cc55cSDimitry Andriclet Predicates= [iHasE2] in { 776349cc55cSDimitry Andric let isCodeGenOnly = 1 in { 777fe6060f1SDimitry Andric def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>; 778fe6060f1SDimitry Andric def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>; 779349cc55cSDimitry Andric } 780fe6060f1SDimitry Andric def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>; 781349cc55cSDimitry Andric let Size = 4, isCodeGenOnly = 0 in 782349cc55cSDimitry Andric def BGENI : CSKYPseudo<(outs GPR:$dst), (ins uimm5:$imm), "bgeni\t$dst, $imm", []>; 783fe6060f1SDimitry Andric def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>; 784fe6060f1SDimitry Andric def MVC32 : R_Z_1<0x1, 0x8, "mvc32">; 785349cc55cSDimitry Andric let isCodeGenOnly = 1 in 786fe6060f1SDimitry Andric def MOV32 : R_XZ<0x12, 0x1, "mov32">; 787fe6060f1SDimitry Andric 788349cc55cSDimitry Andric let usesCustomInserter = 1 in 789349cc55cSDimitry Andric def ISEL32 : CSKYPseudo<(outs GPR:$dst), (ins CARRY:$cond, GPR:$src1, GPR:$src2), 790349cc55cSDimitry Andric "!isel32\t$dst, $src1, src2", [(set GPR:$dst, (select CARRY:$cond, GPR:$src1, GPR:$src2))]>; 791349cc55cSDimitry Andric} 792fe6060f1SDimitry Andric 793349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 794fe6060f1SDimitry Andric def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">; 79581ad6265SDimitry Andric def CLRF32 : R_Z_2<0xB, 0x1, "clrf32">; 79681ad6265SDimitry Andric def CLRT32 : R_Z_2<0xB, 0x2, "clrt32">; 797349cc55cSDimitry Andric} 798fe6060f1SDimitry Andric 799fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 800fe6060f1SDimitry Andric// Branch and call instructions. 801fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 802fe6060f1SDimitry Andric 803fe6060f1SDimitry Andriclet isBranch = 1, isTerminator = 1 in { 804fe6060f1SDimitry Andric let isBarrier = 1, isPredicable = 1 in 805fe6060f1SDimitry Andric def BR32 : I_16_L<0x0, (outs), (ins br_symbol:$imm16), "br32\t$imm16", 806fe6060f1SDimitry Andric [(br bb:$imm16)]>; 807fe6060f1SDimitry Andric 808fe6060f1SDimitry Andric def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16), 809349cc55cSDimitry Andric "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>, Requires<[iHasE2]>; 810fe6060f1SDimitry Andric def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16), 811349cc55cSDimitry Andric "bf32\t$imm16", []>, Requires<[iHasE2]>; 812fe6060f1SDimitry Andric} 813fe6060f1SDimitry Andric 814349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 815fe6060f1SDimitry Andric def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>; 816fe6060f1SDimitry Andric def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>; 817fe6060f1SDimitry Andric def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>; 818fe6060f1SDimitry Andric def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>; 819fe6060f1SDimitry Andric def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>; 820fe6060f1SDimitry Andric def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>; 821fe6060f1SDimitry Andric 822fe6060f1SDimitry Andric let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 823fe6060f1SDimitry Andric def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register 824fe6060f1SDimitry Andric def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16), 825fe6060f1SDimitry Andric "jmpi32\t$imm16", []>; 826fe6060f1SDimitry Andric } 827fe6060f1SDimitry Andric 828fe6060f1SDimitry Andric let isCall = 1, Defs = [ R15 ] in 829fe6060f1SDimitry Andric def JSR32 : I_16_JX<0x7, "jsr32", []>; 830fe6060f1SDimitry Andric 831fe6060f1SDimitry Andric let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in 832fe6060f1SDimitry Andric def JSRI32: I_16_L<0x17, (outs), 833fe6060f1SDimitry Andric (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>; 834349cc55cSDimitry Andric} 835fe6060f1SDimitry Andric 836349cc55cSDimitry Andricdef BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a, 837349cc55cSDimitry Andric (outs GPR:$rx_u), (ins GPR:$rx, br_symbol:$imm16), "bnezad32\t$rx, $imm16", []> { 838349cc55cSDimitry Andric bits<5> rx; 839349cc55cSDimitry Andric bits<16> imm16; 840349cc55cSDimitry Andric let Inst{25 - 21} = 0x1; 841349cc55cSDimitry Andric let Inst{20 - 16} = rx; 842349cc55cSDimitry Andric let Inst{15 - 0} = imm16; 843349cc55cSDimitry Andric let isBranch = 1; 844349cc55cSDimitry Andric let isTerminator = 1; 845349cc55cSDimitry Andric let Constraints = "$rx_u = $rx"; 846349cc55cSDimitry Andric let Predicates = [iHas2E3, iHas10E60]; 847349cc55cSDimitry Andric} 848fe6060f1SDimitry Andric 849fe6060f1SDimitry Andricdef BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>; 850fe6060f1SDimitry Andric 851fe6060f1SDimitry Andricdef BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{ 852fe6060f1SDimitry Andric let isCodeGenOnly = 1; 853fe6060f1SDimitry Andric let isBranch = 1; 854fe6060f1SDimitry Andric let isTerminator = 1; 855fe6060f1SDimitry Andric let isBarrier = 1; 856fe6060f1SDimitry Andric let isPredicable = 1; 857fe6060f1SDimitry Andric let Defs = [ R15 ]; 858fe6060f1SDimitry Andric} 859fe6060f1SDimitry Andric 860fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 861fe6060f1SDimitry Andric// Symbol address instructions. 862fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 863fe6060f1SDimitry Andric 864349cc55cSDimitry Andricdef data_symbol_b : data_symbol<"CSKY::fixup_csky_doffset_imm18", 0>; 865349cc55cSDimitry Andricdef data_symbol_h : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale2", 1>; 866349cc55cSDimitry Andricdef data_symbol_w : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale4", 2> { 867349cc55cSDimitry Andric let ParserMatchClass = DataAsmClass; 868349cc55cSDimitry Andric} 869349cc55cSDimitry Andric 870349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 871349cc55cSDimitry Andric 872fe6060f1SDimitry Andricdef GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset", 873fe6060f1SDimitry Andric (outs GPR:$rz), (ins bare_symbol:$offset), []>; 874349cc55cSDimitry Andric 875349cc55cSDimitry Andriclet Uses = [R28] in { 876349cc55cSDimitry Andricdef LRS32B : I_18_Z_L<0x0, "lrs32.b\t$rz, $offset", 877349cc55cSDimitry Andric (outs GPR:$rz), (ins data_symbol_b:$offset), []>; 878349cc55cSDimitry Andricdef LRS32H : I_18_Z_L<0x1, "lrs32.h\t$rz, $offset", 879349cc55cSDimitry Andric (outs GPR:$rz), (ins data_symbol_h:$offset), []>; 880349cc55cSDimitry Andricdef LRS32W : I_18_Z_L<0x2, "lrs32.w\t$rz, $offset", 881349cc55cSDimitry Andric (outs GPR:$rz), (ins data_symbol_w:$offset), []>; 882349cc55cSDimitry Andricdef SRS32B : I_18_Z_L<0x4, "srs32.b\t$rz, $offset", 883349cc55cSDimitry Andric (outs), (ins GPR:$rz, data_symbol_b:$offset), []>; 884349cc55cSDimitry Andricdef SRS32H : I_18_Z_L<0x5, "srs32.h\t$rz, $offset", 885349cc55cSDimitry Andric (outs), (ins GPR:$rz, data_symbol_h:$offset), []>; 886349cc55cSDimitry Andricdef SRS32W : I_18_Z_L<0x6, "srs32.w\t$rz, $offset", 887349cc55cSDimitry Andric (outs), (ins GPR:$rz, data_symbol_w:$offset), []>; 888349cc55cSDimitry Andric} 889349cc55cSDimitry Andric 890349cc55cSDimitry Andricdef PUSH32 : I_12_PP<0b11111, 0b00000, (outs), (ins reglist:$regs, variable_ops), "push32 $regs">; 891349cc55cSDimitry Andric 892349cc55cSDimitry Andriclet Uses = [R14, R15], isReturn = 1, isTerminator = 1, isBarrier = 1 in 893349cc55cSDimitry Andricdef POP32 : I_12_PP<0b11110, 0b00000, (outs), (ins reglist:$regs, variable_ops), "pop32 $regs">; 894349cc55cSDimitry Andric 895349cc55cSDimitry Andric} 896fe6060f1SDimitry Andric 897fe6060f1SDimitry Andriclet mayLoad = 1, mayStore = 0 in { 898fe6060f1SDimitry Andricdef LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>; 899fe6060f1SDimitry Andriclet isCodeGenOnly = 1 in 900349cc55cSDimitry Andricdef LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>; 901fe6060f1SDimitry Andric} 902fe6060f1SDimitry Andric 903349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 904349cc55cSDimitry Andric// Atomic and fence instructions. 905349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 906349cc55cSDimitry Andric 907349cc55cSDimitry Andriclet Predicates = [iHasMP1E2] in { 908349cc55cSDimitry Andric def BRWARW : BAR<0b01111, "bar.brwarw", 0>; 909349cc55cSDimitry Andric def BRWARWS : BAR<0b01111, "bar.brwarws", 1>; 910349cc55cSDimitry Andric def BRARW : BAR<0b00111, "bar.brarw", 0>; 911349cc55cSDimitry Andric def BRARWS : BAR<0b00111, "bar.brarws", 1>; 912349cc55cSDimitry Andric def BRWAW : BAR<0b01110, "bar.brwaw", 0>; 913349cc55cSDimitry Andric def BRWAWS : BAR<0b01110, "bar.brwaws", 1>; 914349cc55cSDimitry Andric def BRAR : BAR<0b00101, "bar.brar", 0>; 915349cc55cSDimitry Andric def BRARS : BAR<0b00101, "bar.brars", 1>; 916349cc55cSDimitry Andric def BWAW : BAR<0b01010, "bar.bwaw", 0>; 917349cc55cSDimitry Andric def BWAWS : BAR<0b01010, "bar.bwaws", 1>; 918349cc55cSDimitry Andric 919349cc55cSDimitry Andric def LDEX32W : I_LD<AddrMode32WD, 0x7, "ldex32.w", uimm12_2>; 920349cc55cSDimitry Andric let Constraints = "$rd = $rz" in 921349cc55cSDimitry Andric def STEX32W : I_LDST<AddrMode32WD, 0x37, 7, 922349cc55cSDimitry Andric (outs GPR:$rd), (ins GPR:$rz, GPR:$rx, uimm12_2:$imm12), "stex32.w", []>; 923349cc55cSDimitry Andric} 924349cc55cSDimitry Andric 925349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 926349cc55cSDimitry Andric// Other operation instructions. 927349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 928349cc55cSDimitry Andric 929349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 930349cc55cSDimitry Andric def BREV32 : R_XZ<0x18, 0x10, "brev32">; 931349cc55cSDimitry Andric def ABS32 : R_XZ<0x0, 0x10, "abs32">; 932349cc55cSDimitry Andric def BGENR32 : R_XZ<0x14, 0x2, "bgenr32">; 933bdd1243dSDimitry Andric def REVB32 : R_XZ<0x18, 0x4, "revb32">; 934bdd1243dSDimitry Andric def REVH32 : R_XZ<0x18, 0x8, "revh32">; 935349cc55cSDimitry Andric} 936349cc55cSDimitry Andric 937349cc55cSDimitry Andriclet Predicates = [iHasE2] in { 938349cc55cSDimitry Andric def FF0 : R_XZ<0x1F, 0x1, "ff0.32">; 939349cc55cSDimitry Andric def FF1 : R_XZ<0x1F, 0x2, "ff1.32">; 940349cc55cSDimitry Andric def XTRB0 : R_XZ<0x1C, 0x1, "xtrb0.32">; 941349cc55cSDimitry Andric def XTRB1 : R_XZ<0x1C, 0x2, "xtrb1.32">; 942349cc55cSDimitry Andric def XTRB2 : R_XZ<0x1C, 0x4, "xtrb2.32">; 943349cc55cSDimitry Andric def XTRB3 : R_XZ<0x1C, 0x8, "xtrb3.32">; 944349cc55cSDimitry Andric def BTSTI32 : I_5_X<0x0A, 0x4, "btsti32", uimm5, []>; 945349cc55cSDimitry Andric def BCLRI32 : I_5_XZ<0xA, 0x1, "bclri32", 946349cc55cSDimitry Andric (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>; 947349cc55cSDimitry Andric def BSETI32 : I_5_XZ<0xA, 0x2, "bseti32", 948349cc55cSDimitry Andric (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>; 949349cc55cSDimitry Andric} 950349cc55cSDimitry Andric 951349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 952349cc55cSDimitry Andric// Special instructions. 953349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 954349cc55cSDimitry Andric 955349cc55cSDimitry Andricdef MFFCR : CSKY32Inst<AddrModeNone, 0x30, 956349cc55cSDimitry Andric (outs GPR:$rx), (ins), "mfcr\t$rx, fcr", []> { 957349cc55cSDimitry Andric bits<5> rx; 958349cc55cSDimitry Andric 959349cc55cSDimitry Andric let Inst{25 - 21} = 0b00010; 960349cc55cSDimitry Andric let Inst{20 - 16} = 0b00001; 961349cc55cSDimitry Andric let Inst{15 - 10} = 0b011000; 962349cc55cSDimitry Andric let Inst{9 - 5} = 0b00001; 963349cc55cSDimitry Andric let Inst{4 - 0} = rx; 964349cc55cSDimitry Andric let hasSideEffects = 1; 965349cc55cSDimitry Andric let isCodeGenOnly = 1; 966349cc55cSDimitry Andric} 967349cc55cSDimitry Andric 968349cc55cSDimitry Andricdef MTFCR : CSKY32Inst<AddrModeNone, 0x30, 969349cc55cSDimitry Andric (outs), (ins GPR:$rx), "mtcr\t$rx, fcr", []> { 970349cc55cSDimitry Andric bits<5> rx; 971349cc55cSDimitry Andric 972349cc55cSDimitry Andric let Inst{25 - 21} = 0b00010; 973349cc55cSDimitry Andric let Inst{20 - 16} = rx; 974349cc55cSDimitry Andric let Inst{15 - 10} = 0b011001; 975349cc55cSDimitry Andric let Inst{9 - 5} = 0b00001; 976349cc55cSDimitry Andric let Inst{4 - 0} = 0b00001; 977349cc55cSDimitry Andric let hasSideEffects = 1; 978349cc55cSDimitry Andric let isCodeGenOnly = 1; 979349cc55cSDimitry Andric} 980349cc55cSDimitry Andric 981349cc55cSDimitry Andricdef SYNC32 : I_5_IMM5<0x30, 0b000001, 0b00001, "sync32", uimm5, []>; 982349cc55cSDimitry Andric 983349cc55cSDimitry Andricdef SYNC0_32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), 984349cc55cSDimitry Andric "sync32", []> { 985349cc55cSDimitry Andric let Inst{25 - 21} = 0; 986349cc55cSDimitry Andric let Inst{20 - 16} = 0; 987349cc55cSDimitry Andric let Inst{15 - 10} = 0b000001; 988349cc55cSDimitry Andric let Inst{9 - 5} = 0b00001; 989349cc55cSDimitry Andric let Inst{4 - 0} = 0; 990349cc55cSDimitry Andric} 991349cc55cSDimitry Andric 992349cc55cSDimitry Andricdef SYNC_32_I : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), 993349cc55cSDimitry Andric "sync32.i", []> { 994349cc55cSDimitry Andric let Inst{25 - 21} = 1; 995349cc55cSDimitry Andric let Inst{20 - 16} = 0; 996349cc55cSDimitry Andric let Inst{15 - 10} = 0b000001; 997349cc55cSDimitry Andric let Inst{9 - 5} = 0b00001; 998349cc55cSDimitry Andric let Inst{4 - 0} = 0; 999349cc55cSDimitry Andric} 1000349cc55cSDimitry Andric 1001349cc55cSDimitry Andricdef SYNC_32_S : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), 1002349cc55cSDimitry Andric "sync32.s", []> { 1003349cc55cSDimitry Andric let Inst{25 - 21} = 0b10000; 1004349cc55cSDimitry Andric let Inst{20 - 16} = 0; 1005349cc55cSDimitry Andric let Inst{15 - 10} = 0b000001; 1006349cc55cSDimitry Andric let Inst{9 - 5} = 0b00001; 1007349cc55cSDimitry Andric let Inst{4 - 0} = 0; 1008349cc55cSDimitry Andric} 1009349cc55cSDimitry Andric 1010349cc55cSDimitry Andricdef SYNC_32_IS : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), 1011349cc55cSDimitry Andric "sync32.is", []> { 1012349cc55cSDimitry Andric let Inst{25 - 21} = 0b10001; 1013349cc55cSDimitry Andric let Inst{20 - 16} = 0; 1014349cc55cSDimitry Andric let Inst{15 - 10} = 0b000001; 1015349cc55cSDimitry Andric let Inst{9 - 5} = 0b00001; 1016349cc55cSDimitry Andric let Inst{4 - 0} = 0; 1017349cc55cSDimitry Andric} 1018349cc55cSDimitry Andric 1019349cc55cSDimitry Andriclet Predicates = [iHas2E3] in { 1020349cc55cSDimitry Andric def RFI32 : I_5_XZ_PRIVI<0x11, 0x1, "rfi32">; 1021349cc55cSDimitry Andric def SCE32 : I_5_IMM5<0x30, 0b000110, 0b00001, "sce32", uimm4, []>; 1022349cc55cSDimitry Andric} 1023349cc55cSDimitry Andriclet Predicates = [HasExtendLrw] in 1024349cc55cSDimitry Andricdef IDLY32 : I_5_IMM5<0x30, 0b000111, 0b00001, "idly32", imm5_idly, []>; 1025349cc55cSDimitry Andricdef STOP32 : I_5_XZ_PRIVI<0x12, 0x1, "stop32">; 1026349cc55cSDimitry Andricdef WAIT32 : I_5_XZ_PRIVI<0x13, 0x1, "wait32">; 1027349cc55cSDimitry Andricdef DOZE32 : I_5_XZ_PRIVI<0x14, 0x1, "doze32">; 1028349cc55cSDimitry Andricdef WE32 : I_5_XZ_PRIVI<0b010101, 0x1, "we32">; 1029349cc55cSDimitry Andricdef SE32 : I_5_XZ_PRIVI<0b010110, 0x1, "se32">; 1030349cc55cSDimitry Andricdef WSC32 : I_5_XZ_PRIVI<0b001111, 0x1, "wsc32">; 1031349cc55cSDimitry Andric 1032349cc55cSDimitry Andricdef CPOP32 : I_CPOP<(outs), (ins uimm5:$cpid, uimm20:$usdef), "cpop32 <$cpid, ${usdef}>">; 1033349cc55cSDimitry Andricdef CPRC32 : I_CP<0b0100, (outs CARRY:$ca), (ins uimm5:$cpid, uimm12:$usdef), "cprc32 <$cpid, ${usdef}>">; 1034349cc55cSDimitry Andricdef CPRCR32 : I_CP_Z<0b0010, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprcr32 $rz, <$cpid, ${usdef}>">; 1035349cc55cSDimitry Andricdef CPRGR32 : I_CP_Z<0b0000, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprgr32 $rz, <$cpid, ${usdef}>">; 1036349cc55cSDimitry Andricdef CPWCR32 : I_CP_Z<0b0011, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwcr32 $rz, <$cpid, ${usdef}>">; 1037349cc55cSDimitry Andricdef CPWGR32 : I_CP_Z<0b0001, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwgr32 $rz, <$cpid, ${usdef}>">; 1038349cc55cSDimitry Andric 1039349cc55cSDimitry Andriclet Predicates = [iHas3r2E3r3] in { 1040349cc55cSDimitry Andricdef DCACHE_IALL32 : I_5_CACHE<0b100101, 0b01000, "dcache32.iall">; 1041349cc55cSDimitry Andricdef DCACHE_CALL32 : I_5_CACHE<0b100101, 0b00100, "dcache32.call">; 1042349cc55cSDimitry Andricdef DCACHE_CIALL32 : I_5_CACHE<0b100101, 0b01100, "dcache32.ciall">; 1043349cc55cSDimitry Andricdef DCACHE_IVA32 : I_5_X_CACHE<0b100101, 0b01011, "dcache32.iva">; 1044349cc55cSDimitry Andricdef DCACHE_ISW32: I_5_X_CACHE<0b100101, 0b01010, "dcache32.isw">; 1045349cc55cSDimitry Andricdef DCACHE_CVA32 : I_5_X_CACHE<0b100101, 0b00111, "dcache32.cva">; 1046349cc55cSDimitry Andricdef DCACHE_CVAL32 : I_5_X_CACHE<0b100101, 0b10111, "dcache32.cval1">; 1047349cc55cSDimitry Andricdef DCACHE_CSW32 : I_5_X_CACHE<0b100101, 0b00110, "dcache32.csw">; 1048349cc55cSDimitry Andricdef DCACHE_CIVA32 : I_5_X_CACHE<0b100101, 0b01111, "dcache32.civa">; 1049349cc55cSDimitry Andricdef DCACHE_CISW32 : I_5_X_CACHE<0b100101, 0b01110, "dcache32.cisw">; 1050349cc55cSDimitry Andric 1051349cc55cSDimitry Andricdef ICACHE_IALL32 : I_5_CACHE<0b100100, 0b01000, "icache32.iall">; 1052349cc55cSDimitry Andricdef ICACHE_IALLS32 : I_5_CACHE<0b100100, 0b11000, "icache32.ialls">; 1053349cc55cSDimitry Andricdef ICACHE_IVA32 : I_5_X_CACHE<0b100100, 0b01011, "icache32.iva">; 1054349cc55cSDimitry Andric 1055349cc55cSDimitry Andricdef TLBI_VAA32 : I_5_X_CACHE<0b100010, 0b00010, "tlbi32.vaa">; 1056349cc55cSDimitry Andricdef TLBI_VAAS32 : I_5_X_CACHE<0b100010, 0b10010, "tlbi32.vaas">; 1057349cc55cSDimitry Andricdef TLBI_ASID32 : I_5_X_CACHE<0b100010, 0b00001, "tlbi32.asid">; 1058349cc55cSDimitry Andricdef TLBI_ASIDS32 : I_5_X_CACHE<0b100010, 0b10001, "tlbi32.asids">; 1059349cc55cSDimitry Andricdef TLBI_VA32 : I_5_X_CACHE<0b100010, 0b00011, "tlbi32.va">; 1060349cc55cSDimitry Andricdef TLBI_VAS32 : I_5_X_CACHE<0b100010, 0b10011, "tlbi32.vas">; 1061349cc55cSDimitry Andricdef TLBI_ALL32 : I_5_CACHE<0b100010, 0b00000, "tlbi32.all">; 1062349cc55cSDimitry Andricdef TLBI_ALLS32 : I_5_CACHE<0b100010, 0b10000, "tlbi32.alls">; 1063349cc55cSDimitry Andric 1064349cc55cSDimitry Andricdef L2CACHE_IALL : I_5_CACHE<0b100110, 0b01000, "l2cache.iall">; 1065349cc55cSDimitry Andricdef L2CACHE_CALL : I_5_CACHE<0b100110, 0b00100, "l2cache.call">; 1066349cc55cSDimitry Andricdef L2CACHE_CIALL : I_5_CACHE<0b100110, 0b01100, "l2cache.ciall">; 1067349cc55cSDimitry Andric} 1068349cc55cSDimitry Andric 1069349cc55cSDimitry Andricdef PLDR32 :I_PLDR<AddrMode32WD, 0x36, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldr32", []>; 1070349cc55cSDimitry Andricdef PLDW32 :I_PLDR<AddrMode32WD, 0x37, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldw32", []>; 1071349cc55cSDimitry Andric 1072349cc55cSDimitry Andricdef TRAP32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins uimm2:$imm2), "trap32 ${imm2}", []> { 1073349cc55cSDimitry Andric bits<2> imm2; 1074349cc55cSDimitry Andric 1075349cc55cSDimitry Andric let Inst{25 - 21} = 0; 1076349cc55cSDimitry Andric let Inst{20 - 16} = 0; 1077349cc55cSDimitry Andric let Inst{15 - 12} = 0b0010; 1078349cc55cSDimitry Andric let Inst{11 - 10} = imm2; 1079349cc55cSDimitry Andric let Inst{9 - 5} = 0b00001; 1080349cc55cSDimitry Andric let Inst{4 - 0} = 0; 1081349cc55cSDimitry Andric 1082349cc55cSDimitry Andric} 1083349cc55cSDimitry Andric 10840eae32dcSDimitry Andric//===----------------------------------------------------------------------===// 10850eae32dcSDimitry Andric// Instruction Patterns. 10860eae32dcSDimitry Andric//===----------------------------------------------------------------------===// 10870eae32dcSDimitry Andric 10880eae32dcSDimitry Andric// Load & Store Patterns 10890eae32dcSDimitry Andricmulticlass LdPat<PatFrag LoadOp, ImmLeaf imm_type, Instruction Inst, ValueType Type> { 10900eae32dcSDimitry Andric def : Pat<(Type (LoadOp GPR:$rs1)), (Inst GPR:$rs1, 0)>; 10910eae32dcSDimitry Andric def : Pat<(Type (LoadOp (i32 frameindex:$rs1))), (Inst (i32 (to_tframeindex tframeindex:$rs1)), 0)>; 10920eae32dcSDimitry Andric def : Pat<(Type (LoadOp (add GPR:$rs1, imm_type:$uimm))), 10930eae32dcSDimitry Andric (Inst GPR:$rs1, imm_type:$uimm)>; 10940eae32dcSDimitry Andric def : Pat<(Type (LoadOp (add frameindex:$rs1, imm_type:$uimm))), 10950eae32dcSDimitry Andric (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>; 10960eae32dcSDimitry Andric def : Pat<(Type (LoadOp (eqToAdd frameindex:$rs1, imm_type:$uimm))), 10970eae32dcSDimitry Andric (Inst (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm)>; 10980eae32dcSDimitry Andric def : Pat<(Type (LoadOp (add GPR:$rs1, tglobaladdr:$gd))), 10990eae32dcSDimitry Andric (Inst GPR:$rs1, tglobaladdr:$gd)>; 11000eae32dcSDimitry Andric} 11010eae32dcSDimitry Andric 11020eae32dcSDimitry Andricdefm : LdPat<extloadi8, uimm12, LD32B, i32>; 11030eae32dcSDimitry Andricdefm : LdPat<zextloadi8, uimm12, LD32B, i32>; 11040eae32dcSDimitry Andriclet Predicates = [iHasE2] in { 11050eae32dcSDimitry Andric defm : LdPat<sextloadi8, uimm12, LD32BS, i32>; 11060eae32dcSDimitry Andric} 11070eae32dcSDimitry Andricdefm : LdPat<extloadi16, uimm12_1, LD32H, i32>; 11080eae32dcSDimitry Andricdefm : LdPat<zextloadi16, uimm12_1, LD32H, i32>; 11090eae32dcSDimitry Andriclet Predicates = [iHasE2] in { 11100eae32dcSDimitry Andricdefm : LdPat<sextloadi16, uimm12_1, LD32HS, i32>; 11110eae32dcSDimitry Andric} 11120eae32dcSDimitry Andricdefm : LdPat<load, uimm12_2, LD32W, i32>; 11130eae32dcSDimitry Andric 11140eae32dcSDimitry Andricmulticlass LdrPat<PatFrag LoadOp, Instruction Inst, ValueType Type> { 11150eae32dcSDimitry Andric def : Pat<(Type (LoadOp (add GPR:$rs1, GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2, 0)>; 11160eae32dcSDimitry Andric def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 1))))), (Inst GPR:$rs1, GPR:$rs2, 1)>; 11170eae32dcSDimitry Andric def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 2))))), (Inst GPR:$rs1, GPR:$rs2, 2)>; 11180eae32dcSDimitry Andric def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 3))))), (Inst GPR:$rs1, GPR:$rs2, 3)>; 11190eae32dcSDimitry Andric} 11200eae32dcSDimitry Andric 11210eae32dcSDimitry Andriclet Predicates = [iHas2E3] in { 11220eae32dcSDimitry Andric defm : LdrPat<zextloadi8, LDR32B, i32>; 11230eae32dcSDimitry Andric defm : LdrPat<sextloadi8, LDR32BS, i32>; 11240eae32dcSDimitry Andric defm : LdrPat<extloadi8, LDR32BS, i32>; 11250eae32dcSDimitry Andric defm : LdrPat<zextloadi16, LDR32H, i32>; 11260eae32dcSDimitry Andric defm : LdrPat<sextloadi16, LDR32HS, i32>; 11270eae32dcSDimitry Andric defm : LdrPat<extloadi16, LDR32HS, i32>; 11280eae32dcSDimitry Andric defm : LdrPat<load, LDR32W, i32>; 11290eae32dcSDimitry Andric} 11300eae32dcSDimitry Andric 11310eae32dcSDimitry Andricmulticlass StPat<PatFrag StoreOp, ValueType Type, ImmLeaf imm_type, Instruction Inst> { 11320eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rs2, GPR:$rs1), (Inst Type:$rs2, GPR:$rs1, 0)>; 11330eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rs2, frameindex:$rs1), (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), 0)>; 11340eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rs2, (add GPR:$rs1, imm_type:$uimm12)), 11350eae32dcSDimitry Andric (Inst Type:$rs2, GPR:$rs1, imm_type:$uimm12)>; 11360eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rs2, (add frameindex:$rs1, imm_type:$uimm12)), 11370eae32dcSDimitry Andric (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>; 11380eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rs2, (eqToAdd frameindex:$rs1, imm_type:$uimm12)), 11390eae32dcSDimitry Andric (Inst Type:$rs2, (i32 (to_tframeindex tframeindex:$rs1)), imm_type:$uimm12)>; 11400eae32dcSDimitry Andric} 11410eae32dcSDimitry Andric 11420eae32dcSDimitry Andricdefm : StPat<truncstorei8, i32, uimm12, ST32B>; 11430eae32dcSDimitry Andricdefm : StPat<truncstorei16, i32, uimm12_1, ST32H>; 11440eae32dcSDimitry Andricdefm : StPat<store, i32, uimm12_2, ST32W>; 11450eae32dcSDimitry Andric 11460eae32dcSDimitry Andricmulticlass StrPat<PatFrag StoreOp, ValueType Type, Instruction Inst> { 11470eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, GPR:$rs2)), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 0)>; 11480eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 1)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 1)>; 11490eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 2)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 2)>; 11500eae32dcSDimitry Andric def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 3)))), (Inst Type:$rz, GPR:$rs1, GPR:$rs2, 3)>; 11510eae32dcSDimitry Andric} 11520eae32dcSDimitry Andric 11530eae32dcSDimitry Andriclet Predicates = [iHas2E3] in { 11540eae32dcSDimitry Andric defm : StrPat<truncstorei8, i32, STR32B>; 11550eae32dcSDimitry Andric defm : StrPat<truncstorei16, i32, STR32H>; 11560eae32dcSDimitry Andric defm : StrPat<store, i32, STR32W>; 11570eae32dcSDimitry Andric 11580eae32dcSDimitry Andric // Sext & Zext Patterns 11590eae32dcSDimitry Andric def : Pat<(sext_inreg GPR:$src, i1), (SEXT32 GPR:$src, 0, 0)>; 11600eae32dcSDimitry Andric def : Pat<(and GPR:$src, 255), (ZEXT32 GPR:$src, 7, 0)>; 11610eae32dcSDimitry Andric def : Pat<(and GPR:$src, 65535), (ZEXT32 GPR:$src, 15, 0)>; 116204eeddc0SDimitry Andric 116304eeddc0SDimitry Andric // Call Patterns 116404eeddc0SDimitry Andric def : Pat<(CSKY_CALL tglobaladdr, tconstpool:$src2), (JSRI32 tconstpool:$src2)>; 116504eeddc0SDimitry Andric def : Pat<(CSKY_CALL texternalsym, tconstpool:$src2), (JSRI32 tconstpool:$src2)>; 116604eeddc0SDimitry Andric def : Pat<(CSKY_TAIL tglobaladdr, tconstpool:$src2), (JMPI32 tconstpool:$src2)>; 116704eeddc0SDimitry Andric def : Pat<(CSKY_TAIL texternalsym, tconstpool:$src2), (JMPI32 tconstpool:$src2)>; 116804eeddc0SDimitry Andric 116904eeddc0SDimitry Andric def : Pat<(CSKY_CALLReg GPR:$src), (JSR32 GPR:$src)>; 117004eeddc0SDimitry Andric def : Pat<(CSKY_TAILReg GPR:$src), (JMP32 GPR:$src)>; 117104eeddc0SDimitry Andric} 117204eeddc0SDimitry Andric 117304eeddc0SDimitry Andric// Symbol address Patterns 117404eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tglobaladdr, tconstpool:$src2), (LRW32 tconstpool:$src2)>; 117504eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tblockaddress, tconstpool:$src2), (LRW32 tconstpool:$src2)>; 117604eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tjumptable:$src1, tconstpool:$src2), (LRW32_Gen tjumptable:$src1, tconstpool:$src2)>; 117704eeddc0SDimitry Andricdef : Pat<(CSKY_LOAD_ADDR texternalsym, tconstpool:$src2), (LRW32 tconstpool:$src2)>; 1178bdd1243dSDimitry Andricdef : Pat<(CSKY_LOAD_ADDR tconstpool:$src1, tconstpool:$src2), (LRW32_Gen tconstpool:$src1, tconstpool:$src2)>; 117904eeddc0SDimitry Andric 118004eeddc0SDimitry Andriclet Predicates = [iHas2E3] in 118104eeddc0SDimitry Andric def : Pat<(i32 constpool:$src), (GRS32 (to_tconstpool tconstpool:$src))>; 118204eeddc0SDimitry Andric 118304eeddc0SDimitry Andriclet Predicates = [iHasE2] in 118404eeddc0SDimitry Andric def : Pat<(i32 constpool:$src), 118504eeddc0SDimitry Andric (ORI32 (MOVIH32 (to_tconstpool_hi16 tconstpool:$src)), 118604eeddc0SDimitry Andric (to_tconstpool_lo16 tconstpool:$src))>; 118704eeddc0SDimitry Andric 118804eeddc0SDimitry Andricdef : Pat<(i32 (load constpool:$src)), (LRW32 (to_tconstpool tconstpool:$src))>; 118904eeddc0SDimitry Andric 119004eeddc0SDimitry Andric// Branch Patterns. 119104eeddc0SDimitry Andriclet Predicates = [iHasE2] in { 119204eeddc0SDimitry Andricdef : Pat<(brcond CARRY:$ca, bb:$imm16), 119304eeddc0SDimitry Andric (BT32 CARRY:$ca, bb:$imm16)>; 119404eeddc0SDimitry Andric 119506c3fb27SDimitry Andricmulticlass BTF32Pat0<PatFrag cond0, PatFrag cond1, ImmLeaf imm_ty, Instruction inst> { 119606c3fb27SDimitry Andric def : Pat<(brcond (i32 (cond0 GPR:$rs1, uimm16:$rs2)), bb:$imm16), 119706c3fb27SDimitry Andric (BT32 (inst GPR:$rs1, imm_ty:$rs2), bb:$imm16)>; 119806c3fb27SDimitry Andric def : Pat<(brcond (i32 (cond1 GPR:$rs1, uimm16:$rs2)), bb:$imm16), 119906c3fb27SDimitry Andric (BF32 (inst GPR:$rs1, imm_ty:$rs2), bb:$imm16)>; 120006c3fb27SDimitry Andric} 120104eeddc0SDimitry Andric 120206c3fb27SDimitry Andricdefm : BTF32Pat0<setne, seteq, uimm16, CMPNEI32>; 120306c3fb27SDimitry Andricdefm : BTF32Pat0<setuge, setult, oimm16, CMPHSI32>; 120406c3fb27SDimitry Andricdefm : BTF32Pat0<setlt, setge, oimm16, CMPLTI32>; 1205*5f757f3fSDimitry Andric 1206*5f757f3fSDimitry Andricdef : Pat<(brcond (i32 (setne (and GPR:$rs, imm32_1_pop_bit:$im), 0)), bb:$imm16), 1207*5f757f3fSDimitry Andric (BT32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)), 1208*5f757f3fSDimitry Andric bb:$imm16)>; 1209*5f757f3fSDimitry Andricdef : Pat<(brcond (i32 (seteq (and GPR:$rs, imm32_1_pop_bit:$im), 0)), bb:$imm16), 1210*5f757f3fSDimitry Andric (BF32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)), 1211*5f757f3fSDimitry Andric bb:$imm16)>; 121204eeddc0SDimitry Andric} 121304eeddc0SDimitry Andric 121404eeddc0SDimitry Andriclet Predicates = [iHas2E3] in { 121504eeddc0SDimitry Andric 121604eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setne GPR:$rs1, GPR:$rs2)), bb:$imm16), 121704eeddc0SDimitry Andric (BT32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; 121804eeddc0SDimitry Andricdef : Pat<(brcond (i32 (seteq GPR:$rs1, GPR:$rs2)), bb:$imm16), 121904eeddc0SDimitry Andric (BF32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; 122006c3fb27SDimitry Andric 122106c3fb27SDimitry Andricmulticlass BTF32Pat1<PatFrag cond0, PatFrag cond1, Instruction cmp, 122206c3fb27SDimitry Andric Instruction br> { 122306c3fb27SDimitry Andric def : Pat<(brcond (i32 (cond0 GPR:$rs1, GPR:$rs2)), bb:$imm16), 122406c3fb27SDimitry Andric (br (cmp GPR:$rs1, GPR:$rs2), bb:$imm16)>; 122506c3fb27SDimitry Andric def : Pat<(brcond (i32 (cond1 GPR:$rs1, GPR:$rs2)), bb:$imm16), 122606c3fb27SDimitry Andric (br (cmp GPR:$rs2, GPR:$rs1), bb:$imm16)>; 122706c3fb27SDimitry Andric} 122806c3fb27SDimitry Andric 122906c3fb27SDimitry Andricdefm : BTF32Pat1<setuge, setule, CMPHS32, BT32>; 123006c3fb27SDimitry Andricdefm : BTF32Pat1<setult, setugt, CMPHS32, BF32>; 123106c3fb27SDimitry Andricdefm : BTF32Pat1<setlt, setgt, CMPLT32, BT32>; 123206c3fb27SDimitry Andricdefm : BTF32Pat1<setge, setle, CMPLT32, BF32>; 123304eeddc0SDimitry Andric 123404eeddc0SDimitry Andricdef : Pat<(brcond (i32 (seteq GPR:$rs1, (i32 0))), bb:$imm16), 123504eeddc0SDimitry Andric (BEZ32 GPR:$rs1, bb:$imm16)>; 123604eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setne GPR:$rs1, (i32 0))), bb:$imm16), 123704eeddc0SDimitry Andric (BNEZ32 GPR:$rs1, bb:$imm16)>; 123804eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 0))), bb:$imm16), 123904eeddc0SDimitry Andric (BLZ32 GPR:$rs1, bb:$imm16)>; 124006c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 1))), bb:$imm16), 124106c3fb27SDimitry Andric (BLSZ32 GPR:$rs1, bb:$imm16)>; 124204eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setge GPR:$rs1, (i32 0))), bb:$imm16), 124304eeddc0SDimitry Andric (BHSZ32 GPR:$rs1, bb:$imm16)>; 124406c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setge GPR:$rs1, (i32 1))), bb:$imm16), 124506c3fb27SDimitry Andric (BHZ32 GPR:$rs1, bb:$imm16)>; 124604eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 0))), bb:$imm16), 124704eeddc0SDimitry Andric (BHZ32 GPR:$rs1, bb:$imm16)>; 124806c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 -1))), bb:$imm16), 124906c3fb27SDimitry Andric (BHSZ32 GPR:$rs1, bb:$imm16)>; 125004eeddc0SDimitry Andricdef : Pat<(brcond (i32 (setle GPR:$rs1, (i32 0))), bb:$imm16), 125104eeddc0SDimitry Andric (BLSZ32 GPR:$rs1, bb:$imm16)>; 125206c3fb27SDimitry Andricdef : Pat<(brcond (i32 (setle GPR:$rs1, (i32 -1))), bb:$imm16), 125306c3fb27SDimitry Andric (BLZ32 GPR:$rs1, bb:$imm16)>; 125404eeddc0SDimitry Andric} 125504eeddc0SDimitry Andric 125604eeddc0SDimitry Andric// Compare Patterns. 125704eeddc0SDimitry Andriclet Predicates = [iHas2E3] in { 125804eeddc0SDimitry Andric def : Pat<(setne GPR:$rs1, GPR:$rs2), 125904eeddc0SDimitry Andric (CMPNE32 GPR:$rs1, GPR:$rs2)>; 1260*5f757f3fSDimitry Andric def : Pat<(setne (and GPR:$rs, imm32_1_pop_bit:$im), 0), 1261*5f757f3fSDimitry Andric (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im))>; 126204eeddc0SDimitry Andric def : Pat<(i32 (seteq GPR:$rs1, GPR:$rs2)), 126304eeddc0SDimitry Andric (MVCV32 (CMPNE32 GPR:$rs1, GPR:$rs2))>; 126404eeddc0SDimitry Andric def : Pat<(setuge GPR:$rs1, GPR:$rs2), 126504eeddc0SDimitry Andric (CMPHS32 GPR:$rs1, GPR:$rs2)>; 126604eeddc0SDimitry Andric def : Pat<(setule GPR:$rs1, GPR:$rs2), 126704eeddc0SDimitry Andric (CMPHS32 GPR:$rs2, GPR:$rs1)>; 126804eeddc0SDimitry Andric def : Pat<(i32 (setult GPR:$rs1, GPR:$rs2)), 126904eeddc0SDimitry Andric (MVCV32 (CMPHS32 GPR:$rs1, GPR:$rs2))>; 127004eeddc0SDimitry Andric def : Pat<(i32 (setugt GPR:$rs1, GPR:$rs2)), 127104eeddc0SDimitry Andric (MVCV32 (CMPHS32 GPR:$rs2, GPR:$rs1))>; 127204eeddc0SDimitry Andric def : Pat<(setlt GPR:$rs1, GPR:$rs2), 127304eeddc0SDimitry Andric (CMPLT32 GPR:$rs1, GPR:$rs2)>; 127404eeddc0SDimitry Andric def : Pat<(setgt GPR:$rs1, GPR:$rs2), 127504eeddc0SDimitry Andric (CMPLT32 GPR:$rs2, GPR:$rs1)>; 127604eeddc0SDimitry Andric def : Pat<(i32 (setge GPR:$rs1, GPR:$rs2)), 127704eeddc0SDimitry Andric (MVCV32 (CMPLT32 GPR:$rs1, GPR:$rs2))>; 127804eeddc0SDimitry Andric def : Pat<(i32 (setle GPR:$rs1, GPR:$rs2)), 127904eeddc0SDimitry Andric (MVCV32 (CMPLT32 GPR:$rs2, GPR:$rs1))>; 128004eeddc0SDimitry Andric} 128104eeddc0SDimitry Andric 128204eeddc0SDimitry Andriclet Predicates = [iHasE2] in { 128304eeddc0SDimitry Andric def : Pat<(setne GPR:$rs1, uimm16:$rs2), 128404eeddc0SDimitry Andric (CMPNEI32 GPR:$rs1, uimm16:$rs2)>; 128504eeddc0SDimitry Andric let Predicates = [iHas2E3] in 128604eeddc0SDimitry Andric def : Pat<(i32 (seteq GPR:$rs1, uimm16:$rs2)), 128704eeddc0SDimitry Andric (MVCV32 (CMPNEI32 GPR:$rs1, uimm16:$rs2))>; 128804eeddc0SDimitry Andric def : Pat<(setuge GPR:$rs1, oimm16:$rs2), 128904eeddc0SDimitry Andric (CMPHSI32 GPR:$rs1, oimm16:$rs2)>; 129004eeddc0SDimitry Andric let Predicates = [iHas2E3] in 129104eeddc0SDimitry Andric def : Pat<(i32 (setult GPR:$rs1, oimm16:$rs2)), 129204eeddc0SDimitry Andric (MVCV32 (CMPHSI32 GPR:$rs1, oimm16:$rs2))>; 129304eeddc0SDimitry Andric def : Pat<(setlt GPR:$rs1, oimm16:$rs2), 129404eeddc0SDimitry Andric (CMPLTI32 GPR:$rs1, oimm16:$rs2)>; 129504eeddc0SDimitry Andric let Predicates = [iHas2E3] in 129604eeddc0SDimitry Andric def : Pat<(i32 (setge GPR:$rs1, oimm16:$rs2)), 129704eeddc0SDimitry Andric (MVCV32 (CMPLTI32 GPR:$rs1, oimm16:$rs2))>; 129804eeddc0SDimitry Andric} 129904eeddc0SDimitry Andric 130004eeddc0SDimitry Andric// Select Patterns. 130104eeddc0SDimitry Andriclet Predicates = [iHasE2] in { 1302bdd1243dSDimitry Andric 130306c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false), 130406c3fb27SDimitry Andric (INCT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>; 130506c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false), 130606c3fb27SDimitry Andric (INCF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>; 130706c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false), 130806c3fb27SDimitry Andric (DECT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, 130906c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 131006c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false), 131106c3fb27SDimitry Andric (DECF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$false, GPR:$rx, 131206c3fb27SDimitry Andric (imm_neg_XFORM uimm5:$imm))>; 131306c3fb27SDimitry Andric 131406c3fb27SDimitry Andricmulticlass INCDECPat<PatFrag cond0, PatFrag cond1, Instruction cmp> { 131506c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other), 131606c3fb27SDimitry Andric (INCT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>; 131706c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other), 131806c3fb27SDimitry Andric (INCF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>; 131906c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)), 132006c3fb27SDimitry Andric (INCF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>; 132106c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)), 132206c3fb27SDimitry Andric (INCT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>; 132306c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other), 132406c3fb27SDimitry Andric (DECT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, 132506c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 132606c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other), 132706c3fb27SDimitry Andric (DECF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, 132806c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 132906c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)), 133006c3fb27SDimitry Andric (DECF32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, 133106c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 133206c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, oimm16:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)), 133306c3fb27SDimitry Andric (DECT32 (cmp GPR:$rs1, oimm16:$rs2), GPR:$other, GPR:$rx, 133406c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 133506c3fb27SDimitry Andric} 133606c3fb27SDimitry Andric 133706c3fb27SDimitry Andricdefm : INCDECPat<setuge, setult, CMPHSI32>; 133806c3fb27SDimitry Andricdefm : INCDECPat<setlt, setge, CMPLTI32>; 133906c3fb27SDimitry Andric 134006c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, (add GPR:$rx, uimm5:$imm), GPR:$other), 134106c3fb27SDimitry Andric (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>; 134206c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$other, (add GPR:$rx, uimm5:$imm)), 134306c3fb27SDimitry Andric (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>; 134406c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), (add GPR:$rx, uimm5:$imm), GPR:$other), 134506c3fb27SDimitry Andric (INCT32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>; 134606c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$other, (add GPR:$rx, uimm5:$imm)), 134706c3fb27SDimitry Andric (INCF32 CARRY:$ca, GPR:$other, GPR:$rx, uimm5:$imm)>; 134806c3fb27SDimitry Andric 134906c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, (add GPR:$rx, uimm5_neg:$imm), GPR:$other), 135006c3fb27SDimitry Andric (DECT32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>; 135106c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$other, (add GPR:$rx, uimm5_neg:$imm)), 135206c3fb27SDimitry Andric (DECF32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>; 135306c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), (add GPR:$rx, uimm5_neg:$imm), GPR:$other), 135406c3fb27SDimitry Andric (DECT32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>; 135506c3fb27SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)), 135606c3fb27SDimitry Andric (DECF32 CARRY:$ca, GPR:$other, GPR:$rx, (imm_neg_XFORM uimm5_neg:$imm))>; 135706c3fb27SDimitry Andric 135804eeddc0SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false), 135904eeddc0SDimitry Andric (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>; 136004eeddc0SDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false), 136104eeddc0SDimitry Andric (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>; 136204eeddc0SDimitry Andric 136306c3fb27SDimitry Andricmulticlass MOVTF32Pat0<PatFrag cond0, PatFrag cond1, ImmLeaf imm_ty, Instruction inst> { 136406c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, imm_ty:$rs2)), GPR:$rx, GPR:$false), 136506c3fb27SDimitry Andric (MOVT32 (inst GPR:$rs1, imm_ty:$rs2), GPR:$rx, GPR:$false)>; 136606c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, imm_ty:$rs2)), GPR:$rx, GPR:$false), 136706c3fb27SDimitry Andric (MOVF32 (inst GPR:$rs1, imm_ty:$rs2), GPR:$rx, GPR:$false)>; 136806c3fb27SDimitry Andric} 136904eeddc0SDimitry Andric 137006c3fb27SDimitry Andricdefm : MOVTF32Pat0<setne, seteq, uimm16, CMPNEI32>; 137106c3fb27SDimitry Andricdefm : MOVTF32Pat0<setuge, setult, oimm16, CMPHSI32>; 137206c3fb27SDimitry Andricdefm : MOVTF32Pat0<setlt, setge, oimm16, CMPLTI32>; 1373bdd1243dSDimitry Andric 1374bdd1243dSDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false), 1375bdd1243dSDimitry Andric (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>; 1376bdd1243dSDimitry Andricdef : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false), 1377bdd1243dSDimitry Andric (ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>; 1378bdd1243dSDimitry Andric 1379*5f757f3fSDimitry Andricdef : Pat<(select (i32 (setne (and GPR:$rs, imm32_1_pop_bit:$im), 0)), 1380*5f757f3fSDimitry Andric GPR:$true, GPR:$false), 1381*5f757f3fSDimitry Andric (MOVT32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)), 1382*5f757f3fSDimitry Andric GPR:$true, GPR:$false)>; 1383*5f757f3fSDimitry Andricdef : Pat<(select (i32 (seteq (and GPR:$rs, imm32_1_pop_bit:$im), 0)), 1384*5f757f3fSDimitry Andric GPR:$true, GPR:$false), 1385*5f757f3fSDimitry Andric (MOVF32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)), 1386*5f757f3fSDimitry Andric GPR:$true, GPR:$false)>; 1387*5f757f3fSDimitry Andric} 1388bdd1243dSDimitry Andric 1389bdd1243dSDimitry Andriclet Predicates = [iHas2E3] in { 139006c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false), 139106c3fb27SDimitry Andric (INCT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>; 139206c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false), 139306c3fb27SDimitry Andric (INCF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, uimm5:$imm)>; 139406c3fb27SDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false), 139506c3fb27SDimitry Andric (DECT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, 139606c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 139706c3fb27SDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$false), 139806c3fb27SDimitry Andric (DECF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$false, GPR:$rx, 139906c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 140006c3fb27SDimitry Andric 140106c3fb27SDimitry Andricmulticlass INCPat<PatFrag cond0, PatFrag cond1, Instruction cmp, Instruction inc0, Instruction inc1> { 140206c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other), 140306c3fb27SDimitry Andric (inc0 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>; 140406c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)), 140506c3fb27SDimitry Andric (inc1 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, uimm5:$imm)>; 140606c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$other), 140706c3fb27SDimitry Andric (inc0 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, uimm5:$imm)>; 140806c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5:$imm)), 140906c3fb27SDimitry Andric (inc1 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, uimm5:$imm)>; 141006c3fb27SDimitry Andric} 141106c3fb27SDimitry Andric 141206c3fb27SDimitry Andricdefm : INCPat<setuge, setule, CMPHS32, INCT32, INCF32>; 141306c3fb27SDimitry Andricdefm : INCPat<setult, setugt, CMPHS32, INCF32, INCT32>; 141406c3fb27SDimitry Andricdefm : INCPat<setlt, setgt, CMPLT32, INCT32, INCF32>; 141506c3fb27SDimitry Andricdefm : INCPat<setge, setle, CMPLT32, INCF32, INCT32>; 141606c3fb27SDimitry Andric 141706c3fb27SDimitry Andricmulticlass DECPat<PatFrag cond0, PatFrag cond1, Instruction cmp, Instruction dec0, Instruction dec1> { 141806c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other), 141906c3fb27SDimitry Andric (dec0 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, 142006c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 142106c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)), 142206c3fb27SDimitry Andric (dec1 (cmp GPR:$rs1, GPR:$rs2), GPR:$other, GPR:$rx, 142306c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 142406c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5_neg:$imm), GPR:$other), 142506c3fb27SDimitry Andric (dec0 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, 142606c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 142706c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$other, (add GPR:$rx, uimm5_neg:$imm)), 142806c3fb27SDimitry Andric (dec1 (cmp GPR:$rs2, GPR:$rs1), GPR:$other, GPR:$rx, 142906c3fb27SDimitry Andric (imm_neg_XFORM uimm5_neg:$imm))>; 143006c3fb27SDimitry Andric} 143106c3fb27SDimitry Andric 143206c3fb27SDimitry Andricdefm : DECPat<setuge, setule, CMPHS32, DECT32, DECF32>; 143306c3fb27SDimitry Andricdefm : DECPat<setult, setugt, CMPHS32, DECF32, DECT32>; 143406c3fb27SDimitry Andricdefm : DECPat<setlt, setgt, CMPLT32, DECT32, DECF32>; 143506c3fb27SDimitry Andricdefm : DECPat<setge, setle, CMPLT32, DECF32, DECT32>; 1436bdd1243dSDimitry Andric 1437bdd1243dSDimitry Andricdef : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), 1438bdd1243dSDimitry Andric (MOVT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; 1439bdd1243dSDimitry Andricdef : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), 1440bdd1243dSDimitry Andric (MOVF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; 1441bdd1243dSDimitry Andric 144206c3fb27SDimitry Andricmulticlass MOVTF32Pat1<PatFrag cond0, PatFrag cond1, Instruction cmp_inst, 144306c3fb27SDimitry Andric Instruction mov_inst> { 144406c3fb27SDimitry Andric def : Pat<(select (i32 (cond0 GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), 144506c3fb27SDimitry Andric (mov_inst (cmp_inst GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; 144606c3fb27SDimitry Andric def : Pat<(select (i32 (cond1 GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), 144706c3fb27SDimitry Andric (mov_inst (cmp_inst GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>; 144806c3fb27SDimitry Andric} 144904eeddc0SDimitry Andric 145006c3fb27SDimitry Andricdefm : MOVTF32Pat1<setuge, setule, CMPHS32, MOVT32>; 145106c3fb27SDimitry Andricdefm : MOVTF32Pat1<setult, setugt, CMPHS32, MOVF32>; 145206c3fb27SDimitry Andricdefm : MOVTF32Pat1<setlt, setgt, CMPLT32, MOVT32>; 145306c3fb27SDimitry Andricdefm : MOVTF32Pat1<setge, setle, CMPLT32, MOVF32>; 145404eeddc0SDimitry Andric 145506c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, (i32 0), GPR:$other), 145606c3fb27SDimitry Andric (CLRT32 CARRY:$ca, GPR:$other)>; 145706c3fb27SDimitry Andricdef : Pat<(select CARRY:$ca, GPR:$other, (i32 0)), 145806c3fb27SDimitry Andric (CLRF32 CARRY:$ca, GPR:$other)>; 14590eae32dcSDimitry Andric} 14600eae32dcSDimitry Andric 14610eae32dcSDimitry Andric// Constant materialize patterns. 14620eae32dcSDimitry Andriclet Predicates = [iHasE2] in 14630eae32dcSDimitry Andric def : Pat<(i32 imm:$imm), 14640eae32dcSDimitry Andric (ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>; 14650eae32dcSDimitry Andric 1466*5f757f3fSDimitry Andric// Bit operations. 1467*5f757f3fSDimitry Andriclet Predicates = [iHasE2] in { 1468*5f757f3fSDimitry Andric def : Pat<(or GPR:$rs, imm32_1_pop_bit:$imm), 1469*5f757f3fSDimitry Andric (BSETI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$imm))>; 1470*5f757f3fSDimitry Andric def : Pat<(and GPR:$rs, imm32_1_zero_bit:$imm), 1471*5f757f3fSDimitry Andric (BCLRI32 GPR:$rs, (imm32_1_zero_bit_XFORM imm32_1_zero_bit:$imm))>; 1472*5f757f3fSDimitry Andric} 1473*5f757f3fSDimitry Andric 14740eae32dcSDimitry Andric// Other operations. 14750eae32dcSDimitry Andriclet Predicates = [iHasE2] in { 14760eae32dcSDimitry Andric def : Pat<(rotl GPR:$rs1, GPR:$rs2), 14770eae32dcSDimitry Andric (ROTL32 GPR:$rs1, (ANDI32 GPR:$rs2, 0x1f))>; 14780eae32dcSDimitry Andric let Predicates = [iHas2E3] in { 14790eae32dcSDimitry Andric def : Pat<(bitreverse GPR:$rx), (BREV32 GPR:$rx)>; 14800eae32dcSDimitry Andric def : Pat<(bswap GPR:$rx), (REVB32 GPR:$rx)>; 1481*5f757f3fSDimitry Andric def : Pat<(i32 (cttz GPR:$rx)), (FF1 (BREV32 GPR:$rx))>; 14820eae32dcSDimitry Andric } 14830eae32dcSDimitry Andric def : Pat<(i32 (ctlz GPR:$rx)), (FF1 GPR:$rx)>; 14840eae32dcSDimitry Andric} 1485349cc55cSDimitry Andric 1486349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 1487349cc55cSDimitry Andric// Pseudo for assembly 1488349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 1489349cc55cSDimitry Andric 1490349cc55cSDimitry Andriclet isCall = 1, Defs = [ R15 ], mayLoad = 1, Size = 4, isCodeGenOnly = 0 in 1491349cc55cSDimitry Andricdef JBSR32 : CSKYPseudo<(outs), (ins call_symbol:$src1), "jbsr32\t$src1", []>; 1492349cc55cSDimitry Andric 1493349cc55cSDimitry Andricdef JBR32 : CSKYPseudo<(outs), (ins br_symbol:$src1), "jbr32\t$src1", []> { 1494349cc55cSDimitry Andric let isBranch = 1; 1495349cc55cSDimitry Andric let isTerminator = 1; 1496349cc55cSDimitry Andric let isBarrier = 1; 1497349cc55cSDimitry Andric let isIndirectBranch = 1; 1498349cc55cSDimitry Andric let mayLoad = 1; 1499349cc55cSDimitry Andric let Size = 4; 1500349cc55cSDimitry Andric} 1501349cc55cSDimitry Andric 1502349cc55cSDimitry Andricdef JBT32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbt32\t$src1", []> { 1503349cc55cSDimitry Andric let isBranch = 1; 1504349cc55cSDimitry Andric let isTerminator = 1; 1505349cc55cSDimitry Andric let isIndirectBranch = 1; 1506349cc55cSDimitry Andric let mayLoad = 1; 1507349cc55cSDimitry Andric let Size = 4; 1508349cc55cSDimitry Andric} 1509349cc55cSDimitry Andric 1510349cc55cSDimitry Andricdef JBF32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbf32\t$src1", []> { 1511349cc55cSDimitry Andric let isBranch = 1; 1512349cc55cSDimitry Andric let isTerminator = 1; 1513349cc55cSDimitry Andric let isIndirectBranch = 1; 1514349cc55cSDimitry Andric let mayLoad = 1; 1515349cc55cSDimitry Andric let Size = 4; 1516349cc55cSDimitry Andric} 1517349cc55cSDimitry Andric 1518349cc55cSDimitry Andricdef JBT_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbt_e\t$src1", []> { 1519349cc55cSDimitry Andric let isBranch = 1; 1520349cc55cSDimitry Andric let isTerminator = 1; 1521349cc55cSDimitry Andric let isIndirectBranch = 1; 1522349cc55cSDimitry Andric let mayLoad = 1; 1523349cc55cSDimitry Andric let Size = 6; 1524349cc55cSDimitry Andric} 1525349cc55cSDimitry Andric 1526349cc55cSDimitry Andricdef JBF_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbf_e\t$src1", []> { 1527349cc55cSDimitry Andric let isBranch = 1; 1528349cc55cSDimitry Andric let isTerminator = 1; 1529349cc55cSDimitry Andric let isIndirectBranch = 1; 1530349cc55cSDimitry Andric let mayLoad = 1; 1531349cc55cSDimitry Andric let Size = 6; 1532349cc55cSDimitry Andric} 1533349cc55cSDimitry Andric 1534349cc55cSDimitry Andriclet mayLoad = 1, Size = 2, isCodeGenOnly = 0 in 1535349cc55cSDimitry Andricdef PseudoLRW32 : CSKYPseudo<(outs GPR:$rz), (ins bare_symbol:$src), "lrw32 $rz, $src", []>; 1536349cc55cSDimitry Andric 1537349cc55cSDimitry Andriclet mayLoad = 1, Size = 4, isCodeGenOnly = 0 in 1538349cc55cSDimitry Andricdef PseudoJSRI32 : CSKYPseudo<(outs), (ins call_symbol:$src), "jsri32 $src", []>; 1539349cc55cSDimitry Andric 1540349cc55cSDimitry Andriclet mayLoad = 1, Size = 4, isCodeGenOnly = 0 in 1541349cc55cSDimitry Andricdef PseudoJMPI32 : CSKYPseudo<(outs), (ins br_symbol:$src), "jmpi32 $src", []>; 1542349cc55cSDimitry Andric 1543349cc55cSDimitry Andriclet isNotDuplicable = 1, mayLoad = 1, mayStore = 0, Size = 8 in 1544349cc55cSDimitry Andricdef PseudoTLSLA32 : CSKYPseudo<(outs GPR:$dst1, GPR:$dst2), 1545349cc55cSDimitry Andric (ins constpool_symbol:$src, i32imm:$label), "!tlslrw32\t$dst1, $dst2, $src, $label", []>; 1546349cc55cSDimitry Andric 1547349cc55cSDimitry Andriclet hasSideEffects = 0, isNotDuplicable = 1 in 1548349cc55cSDimitry Andricdef CONSTPOOL_ENTRY : CSKYPseudo<(outs), 1549349cc55cSDimitry Andric (ins i32imm:$instid, i32imm:$cpidx, i32imm:$size), "", []>; 1550349cc55cSDimitry Andric 1551349cc55cSDimitry Andricinclude "CSKYInstrInfo16Instr.td" 155204eeddc0SDimitry Andricinclude "CSKYInstrInfoF1.td" 155304eeddc0SDimitry Andricinclude "CSKYInstrInfoF2.td" 155481ad6265SDimitry Andricinclude "CSKYInstrAlias.td" 1555