diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/CSKY')
41 files changed, 4342 insertions, 146 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp index f2a381190fe7..ebc04b40d428 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp @@ -1,12 +1,12 @@ -//===-- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===// +//===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +#include "MCTargetDesc/CSKYInstPrinter.h" #include "MCTargetDesc/CSKYMCExpr.h" #include "MCTargetDesc/CSKYMCTargetDesc.h" #include "TargetInfo/CSKYTargetInfo.h" @@ -20,10 +20,14 @@ #include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "csky-asm-parser" using namespace llvm; @@ -32,6 +36,8 @@ struct CSKYOperand; class CSKYAsmParser : public MCTargetAsmParser { + const MCRegisterInfo *MRI; + bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, Twine Msg); @@ -52,6 +58,9 @@ class CSKYAsmParser : public MCTargetAsmParser { OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; + bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, + MCStreamer &Out); + // Auto-generated instruction matching functions #define GET_ASSEMBLER_HEADER #include "CSKYGenAsmMatcher.inc" @@ -61,12 +70,18 @@ class CSKYAsmParser : public MCTargetAsmParser { OperandMatchResultTy parseBaseRegImm(OperandVector &Operands); OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands); OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands); + OperandMatchResultTy parseDataSymbol(OperandVector &Operands); + OperandMatchResultTy parsePSRFlag(OperandVector &Operands); + OperandMatchResultTy parseRegSeq(OperandVector &Operands); + OperandMatchResultTy parseRegList(OperandVector &Operands); bool parseOperand(OperandVector &Operands, StringRef Mnemonic); public: enum CSKYMatchResultTy { Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, + Match_RequiresSameSrcAndDst, + Match_InvalidRegOutOfRange, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "CSKYGenAsmMatcher.inc" #undef GET_OPERAND_DIAGNOSTIC_TYPES @@ -81,10 +96,14 @@ public: /// Instances of this class represent a parsed machine instruction. struct CSKYOperand : public MCParsedAsmOperand { + enum KindTy { Token, Register, Immediate, + RegisterSeq, + CPOP, + RegisterList } Kind; struct RegOp { @@ -95,11 +114,34 @@ struct CSKYOperand : public MCParsedAsmOperand { const MCExpr *Val; }; + struct ConstpoolOp { + const MCExpr *Val; + }; + + struct RegSeqOp { + unsigned RegNumFrom; + unsigned RegNumTo; + }; + + struct RegListOp { + unsigned List1From = 0; + unsigned List1To = 0; + unsigned List2From = 0; + unsigned List2To = 0; + unsigned List3From = 0; + unsigned List3To = 0; + unsigned List4From = 0; + unsigned List4To = 0; + }; + SMLoc StartLoc, EndLoc; union { StringRef Tok; RegOp Reg; ImmOp Imm; + ConstpoolOp CPool; + RegSeqOp RegSeq; + RegListOp RegList; }; CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} @@ -113,18 +155,31 @@ public: case Register: Reg = o.Reg; break; + case RegisterSeq: + RegSeq = o.RegSeq; + break; + case CPOP: + CPool = o.CPool; + break; case Immediate: Imm = o.Imm; break; case Token: Tok = o.Tok; break; + case RegisterList: + RegList = o.RegList; + break; } } bool isToken() const override { return Kind == Token; } bool isReg() const override { return Kind == Register; } bool isImm() const override { return Kind == Immediate; } + bool isRegisterSeq() const { return Kind == RegisterSeq; } + bool isRegisterList() const { return Kind == RegisterList; } + bool isConstPoolOp() const { return Kind == CPOP; } + bool isMem() const override { return false; } static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) { @@ -163,29 +218,132 @@ public: return IsConstantImm && isShiftedInt<num, shift>(Imm); } + bool isUImm1() const { return isUImm<1>(); } bool isUImm2() const { return isUImm<2>(); } + bool isUImm3() const { return isUImm<3>(); } + bool isUImm4() const { return isUImm<4>(); } bool isUImm5() const { return isUImm<5>(); } + bool isUImm6() const { return isUImm<6>(); } + bool isUImm7() const { return isUImm<7>(); } + bool isUImm8() const { return isUImm<8>(); } bool isUImm12() const { return isUImm<12>(); } bool isUImm16() const { return isUImm<16>(); } - + bool isUImm20() const { return isUImm<20>(); } + bool isUImm24() const { return isUImm<24>(); } + + bool isOImm3() const { return isOImm<3>(); } + bool isOImm4() const { return isOImm<4>(); } + bool isOImm5() const { return isOImm<5>(); } + bool isOImm6() const { return isOImm<6>(); } + bool isOImm8() const { return isOImm<8>(); } bool isOImm12() const { return isOImm<12>(); } bool isOImm16() const { return isOImm<16>(); } + bool isSImm8() const { return isSImm<8>(); } + + bool isUImm5Shift1() { return isUImm<5, 1>(); } + bool isUImm5Shift2() { return isUImm<5, 2>(); } + bool isUImm7Shift1() { return isUImm<7, 1>(); } + bool isUImm7Shift2() { return isUImm<7, 2>(); } + bool isUImm7Shift3() { return isUImm<7, 3>(); } + bool isUImm8Shift2() { return isUImm<8, 2>(); } + bool isUImm8Shift3() { return isUImm<8, 3>(); } + bool isUImm8Shift8() { return isUImm<8, 8>(); } + bool isUImm8Shift16() { return isUImm<8, 16>(); } + bool isUImm8Shift24() { return isUImm<8, 24>(); } bool isUImm12Shift1() { return isUImm<12, 1>(); } bool isUImm12Shift2() { return isUImm<12, 2>(); } + bool isUImm16Shift8() { return isUImm<16, 8>(); } + bool isUImm16Shift16() { return isUImm<16, 16>(); } + bool isUImm24Shift8() { return isUImm<24, 8>(); } bool isSImm16Shift1() { return isSImm<16, 1>(); } - bool isCSKYSymbol() const { + bool isCSKYSymbol() const { return isImm(); } + + bool isConstpool() const { return isConstPoolOp(); } + bool isDataSymbol() const { return isConstPoolOp(); } + + bool isSPOperand() const { + if (!isReg()) + return false; + return getReg() == CSKY::R14; + } + + bool isPSRFlag() const { int64_t Imm; - // Must be of 'immediate' type but not a constant. - return isImm() && !evaluateConstantImm(getImm(), Imm); + // Must be of 'immediate' type and a constant. + if (!isImm() || !evaluateConstantImm(getImm(), Imm)) + return false; + + return isUInt<5>(Imm); + } + + template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const { + if (!isRegisterSeq()) + return false; + + std::pair<unsigned, unsigned> regSeq = getRegSeq(); + + return MIN <= regSeq.first && regSeq.first <= regSeq.second && + regSeq.second <= MAX; + } + + bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); } + + static bool isLegalRegList(unsigned from, unsigned to) { + if (from == 0 && to == 0) + return true; + + if (from == to) { + if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 && + from != CSKY::R28) + return false; + + return true; + } else { + if (from != CSKY::R4 && from != CSKY::R16) + return false; + + if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12) + return true; + else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18) + return true; + else + return false; + } + } + + bool isRegList() const { + if (!isRegisterList()) + return false; + + auto regList = getRegList(); + + if (!isLegalRegList(regList.List1From, regList.List1To)) + return false; + if (!isLegalRegList(regList.List2From, regList.List2To)) + return false; + if (!isLegalRegList(regList.List3From, regList.List3To)) + return false; + if (!isLegalRegList(regList.List4From, regList.List4To)) + return false; + + return true; } - bool isConstpoolSymbol() const { + bool isExtImm6() { + if (!isImm()) + return false; + int64_t Imm; - // Must be of 'immediate' type but not a constant. - return isImm() && !evaluateConstantImm(getImm(), Imm); + bool IsConstantImm = evaluateConstantImm(getImm(), Imm); + if (!IsConstantImm) + return false; + + int uimm4 = Imm & 0xf; + + return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14; } /// Gets location of the first token of this operand. @@ -198,23 +356,64 @@ public: return Reg.RegNum; } + std::pair<unsigned, unsigned> getRegSeq() const { + assert(Kind == RegisterSeq && "Invalid type access!"); + return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo); + } + + RegListOp getRegList() const { + assert(Kind == RegisterList && "Invalid type access!"); + return RegList; + } + const MCExpr *getImm() const { assert(Kind == Immediate && "Invalid type access!"); return Imm.Val; } + const MCExpr *getConstpoolOp() const { + assert(Kind == CPOP && "Invalid type access!"); + return CPool.Val; + } + StringRef getToken() const { assert(Kind == Token && "Invalid type access!"); return Tok; } void print(raw_ostream &OS) const override { + auto RegName = [](unsigned Reg) { + if (Reg) + return CSKYInstPrinter::getRegisterName(Reg); + else + return "noreg"; + }; + switch (Kind) { + case CPOP: + OS << *getConstpoolOp(); + break; case Immediate: OS << *getImm(); break; - case Register: - OS << "<register x" << getReg() << ">"; + case KindTy::Register: + OS << "<register " << RegName(getReg()) << ">"; + break; + case RegisterSeq: + OS << "<register-seq "; + OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second) + << ">"; + break; + case RegisterList: + OS << "<register-list "; + OS << RegName(getRegList().List1From) << "-" + << RegName(getRegList().List1To) << ","; + OS << RegName(getRegList().List2From) << "-" + << RegName(getRegList().List2To) << ","; + OS << RegName(getRegList().List3From) << "-" + << RegName(getRegList().List3To) << ","; + OS << RegName(getRegList().List4From) << "-" + << RegName(getRegList().List4To); break; case Token: OS << "'" << getToken() << "'"; @@ -239,6 +438,51 @@ public: return Op; } + static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom, + unsigned RegNoTo, SMLoc S) { + auto Op = std::make_unique<CSKYOperand>(RegisterSeq); + Op->RegSeq.RegNumFrom = RegNoFrom; + Op->RegSeq.RegNumTo = RegNoTo; + Op->StartLoc = S; + Op->EndLoc = S; + return Op; + } + + static std::unique_ptr<CSKYOperand> + createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) { + auto Op = std::make_unique<CSKYOperand>(RegisterList); + Op->RegList.List1From = 0; + Op->RegList.List1To = 0; + Op->RegList.List2From = 0; + Op->RegList.List2To = 0; + Op->RegList.List3From = 0; + Op->RegList.List3To = 0; + Op->RegList.List4From = 0; + Op->RegList.List4To = 0; + + for (unsigned i = 0; i < reglist.size(); i += 2) { + if (Op->RegList.List1From == 0) { + Op->RegList.List1From = reglist[i]; + Op->RegList.List1To = reglist[i + 1]; + } else if (Op->RegList.List2From == 0) { + Op->RegList.List2From = reglist[i]; + Op->RegList.List2To = reglist[i + 1]; + } else if (Op->RegList.List3From == 0) { + Op->RegList.List3From = reglist[i]; + Op->RegList.List3To = reglist[i + 1]; + } else if (Op->RegList.List4From == 0) { + Op->RegList.List4From = reglist[i]; + Op->RegList.List4To = reglist[i + 1]; + } else { + assert(0); + } + } + + Op->StartLoc = S; + Op->EndLoc = S; + return Op; + } + static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S, SMLoc E) { auto Op = std::make_unique<CSKYOperand>(Immediate); @@ -248,6 +492,15 @@ public: return Op; } + static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val, + SMLoc S, SMLoc E) { + auto Op = std::make_unique<CSKYOperand>(CPOP); + Op->CPool.Val = Val; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; + } + void addExpr(MCInst &Inst, const MCExpr *Expr) const { assert(Expr && "Expr shouldn't be null!"); if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) @@ -266,6 +519,70 @@ public: assert(N == 1 && "Invalid number of operands!"); addExpr(Inst, getImm()); } + + void addConstpoolOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createExpr(getConstpoolOp())); + } + + void addRegSeqOperands(MCInst &Inst, unsigned N) const { + assert(N == 2 && "Invalid number of operands!"); + auto regSeq = getRegSeq(); + + Inst.addOperand(MCOperand::createReg(regSeq.first)); + Inst.addOperand(MCOperand::createReg(regSeq.second)); + } + + static unsigned getListValue(unsigned ListFrom, unsigned ListTo) { + if (ListFrom == ListTo && ListFrom == CSKY::R15) + return (1 << 4); + else if (ListFrom == ListTo && ListFrom == CSKY::R28) + return (1 << 8); + else if (ListFrom == CSKY::R4) + return ListTo - ListFrom + 1; + else if (ListFrom == CSKY::R16) + return ((ListTo - ListFrom + 1) << 5); + else + return 0; + } + + void addRegListOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + auto regList = getRegList(); + + unsigned V = 0; + + unsigned T = getListValue(regList.List1From, regList.List1To); + if (T != 0) + V = V | T; + + T = getListValue(regList.List2From, regList.List2To); + if (T != 0) + V = V | T; + + T = getListValue(regList.List3From, regList.List3To); + if (T != 0) + V = V | T; + + T = getListValue(regList.List4From, regList.List4To); + if (T != 0) + V = V | T; + + Inst.addOperand(MCOperand::createImm(V)); + } + + bool isValidForTie(const CSKYOperand &Other) const { + if (Kind != Other.Kind) + return false; + + switch (Kind) { + default: + llvm_unreachable("Unexpected kind"); + return false; + case Register: + return Reg.RegNum == Other.Reg.RegNum; + } + } }; } // end anonymous namespace. @@ -299,9 +616,7 @@ bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, default: break; case Match_Success: - Inst.setLoc(IDLoc); - Out.emitInstruction(Inst, getSTI()); - return false; + return processInstruction(Inst, IDLoc, Operands, Out); case Match_MissingFeature: { assert(MissingFeatures.any() && "Unknown missing features!"); ListSeparator LS; @@ -347,26 +662,79 @@ bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, switch (Result) { default: break; + case Match_InvalidSImm8: + return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7), + (1 << 7) - 1); + case Match_InvalidOImm3: + return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3)); + case Match_InvalidOImm4: + return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4)); + case Match_InvalidOImm5: + return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5)); + case Match_InvalidOImm6: + return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6)); + case Match_InvalidOImm8: + return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8)); case Match_InvalidOImm12: return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12)); case Match_InvalidOImm16: return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16)); + case Match_InvalidUImm1: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); case Match_InvalidUImm2: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); + case Match_InvalidUImm3: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); + case Match_InvalidUImm4: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); case Match_InvalidUImm5: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); + case Match_InvalidUImm6: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); + case Match_InvalidUImm7: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); + case Match_InvalidUImm8: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); case Match_InvalidUImm12: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); + case Match_InvalidUImm16: + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); + case Match_InvalidUImm5Shift1: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 5) - 2, + "immediate must be a multiple of 2 bytes in the range"); case Match_InvalidUImm12Shift1: return generateImmOutOfRangeError( Operands, ErrorInfo, 0, (1 << 12) - 2, "immediate must be a multiple of 2 bytes in the range"); + case Match_InvalidUImm5Shift2: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 5) - 4, + "immediate must be a multiple of 4 bytes in the range"); + case Match_InvalidUImm7Shift1: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 7) - 2, + "immediate must be a multiple of 2 bytes in the range"); + case Match_InvalidUImm7Shift2: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 7) - 4, + "immediate must be a multiple of 4 bytes in the range"); + case Match_InvalidUImm8Shift2: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 8) - 4, + "immediate must be a multiple of 4 bytes in the range"); + case Match_InvalidUImm8Shift3: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 8) - 8, + "immediate must be a multiple of 8 bytes in the range"); + case Match_InvalidUImm8Shift8: + return generateImmOutOfRangeError( + Operands, ErrorInfo, 0, (1 << 8) - 256, + "immediate must be a multiple of 256 bytes in the range"); case Match_InvalidUImm12Shift2: return generateImmOutOfRangeError( Operands, ErrorInfo, 0, (1 << 12) - 4, "immediate must be a multiple of 4 bytes in the range"); - case Match_InvalidUImm16: - return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1); case Match_InvalidCSKYSymbol: { SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be a symbol name"); @@ -375,15 +743,68 @@ bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be a constpool symbol name"); } + case Match_InvalidPSRFlag: { + SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "psrset operand is not valid"); + } + case Match_InvalidRegSeq: { + SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "Register sequence is not valid"); } - + case Match_InvalidRegOutOfRange: { + SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "register is out of range"); + } + case Match_InvalidSPOperand: { + SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "operand must be sp register"); + } + case Match_RequiresSameSrcAndDst: { + SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "src and dst operand must be same"); + } + case Match_InvalidRegList: { + SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "invalid register list"); + } + } + LLVM_DEBUG(dbgs() << "Result = " << Result); llvm_unreachable("Unknown match type detected!"); } +bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, + OperandVector &Operands, + MCStreamer &Out) { + + if (Inst.getOpcode() == CSKY::LDQ32 || Inst.getOpcode() == CSKY::STQ32) { + if (Inst.getOperand(1).getReg() != CSKY::R4 || + Inst.getOperand(2).getReg() != CSKY::R7) { + return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected"); + } + Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32); + Out.emitInstruction(Inst, getSTI()); + return false; + } else if (Inst.getOpcode() == CSKY::SEXT32 || + Inst.getOpcode() == CSKY::ZEXT32) { + if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm()) + return Error(IDLoc, "msb must be greater or equal to lsb"); + } else if (Inst.getOpcode() == CSKY::INS32) { + if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm()) + return Error(IDLoc, "msb must be greater or equal to lsb"); + } else if (Inst.getOpcode() == CSKY::IDLY32) { + if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0) + return Error(IDLoc, "n must be in range [0,32]"); + } + + Out.emitInstruction(Inst, getSTI()); + return false; +} + // Attempts to match Name as a register (either using the default name or // alternative ABI names), setting RegNo to the matching register. Upon // failure, returns true and sets RegNo to 0. -static bool matchRegisterNameHelper(MCRegister &RegNo, StringRef Name) { +static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, + MCRegister &RegNo, StringRef Name) { RegNo = MatchRegisterName(Name); if (RegNo == CSKY::NoRegister) @@ -399,12 +820,12 @@ bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, EndLoc = Tok.getEndLoc(); StringRef Name = getLexer().getTok().getIdentifier(); - if (!matchRegisterNameHelper((MCRegister &)RegNo, Name)) { + if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) { getParser().Lex(); // Eat identifier token. return false; } - return Error(StartLoc, "invalid register name"); + return MatchOperand_NoMatch; } OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { @@ -418,7 +839,7 @@ OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) { StringRef Name = getLexer().getTok().getIdentifier(); MCRegister RegNo; - if (matchRegisterNameHelper((MCRegister &)RegNo, Name)) + if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) return MatchOperand_NoMatch; getLexer().Lex(); @@ -439,7 +860,13 @@ OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) { if (parseRegister(Operands) != MatchOperand_Success) { getLexer().UnLex(Tok); Operands.pop_back(); - return MatchOperand_ParseFail; + return MatchOperand_NoMatch; + } + + if (getLexer().is(AsmToken::RParen)) { + Operands.push_back(CSKYOperand::createToken(")", getLoc())); + getParser().Lex(); // Eat ')' + return MatchOperand_Success; } if (getLexer().isNot(AsmToken::Comma)) { @@ -495,8 +922,10 @@ OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) { const MCExpr *IdVal; SMLoc S = getLoc(); - if (getParser().parseExpression(IdVal)) + if (getParser().parseExpression(IdVal)) { + Error(getLoc(), "unknown expression"); return MatchOperand_ParseFail; + } SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); Operands.push_back(CSKYOperand::createImm(IdVal, S, E)); @@ -517,17 +946,26 @@ bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { return true; // Attempt to parse token as register - if (parseRegister(Operands) == MatchOperand_Success) + auto Res = parseRegister(Operands); + if (Res == MatchOperand_Success) return false; + else if (Res == MatchOperand_ParseFail) + return true; // Attempt to parse token as (register, imm) - if (getLexer().is(AsmToken::LParen)) - if (parseBaseRegImm(Operands) == MatchOperand_Success) + if (getLexer().is(AsmToken::LParen)) { + Res = parseBaseRegImm(Operands); + if (Res == MatchOperand_Success) return false; + else if (Res == MatchOperand_ParseFail) + return true; + } - // Attempt to parse token as a imm. - if (parseImmediate(Operands) == MatchOperand_Success) + Res = parseImmediate(Operands); + if (Res == MatchOperand_Success) return false; + else if (Res == MatchOperand_ParseFail) + return true; // Finally we have exhausted all options and must declare defeat. Error(getLoc(), "unknown operand"); @@ -537,16 +975,20 @@ bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); + const MCExpr *Res; if (getLexer().getKind() != AsmToken::Identifier) return MatchOperand_NoMatch; StringRef Identifier; - if (getParser().parseIdentifier(Identifier)) + AsmToken Tok = getLexer().getTok(); + + if (getParser().parseIdentifier(Identifier)) { + Error(getLoc(), "unknown identifier"); return MatchOperand_ParseFail; + } CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; - if (Identifier.consume_back("@GOT")) Kind = CSKYMCExpr::VK_CSKY_GOT; else if (Identifier.consume_back("@GOTOFF")) @@ -555,44 +997,377 @@ OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) { Kind = CSKYMCExpr::VK_CSKY_PLT; else if (Identifier.consume_back("@GOTPC")) Kind = CSKYMCExpr::VK_CSKY_GOTPC; + else if (Identifier.consume_back("@TLSGD32")) + Kind = CSKYMCExpr::VK_CSKY_TLSGD; + else if (Identifier.consume_back("@GOTTPOFF")) + Kind = CSKYMCExpr::VK_CSKY_TLSIE; + else if (Identifier.consume_back("@TPOFF")) + Kind = CSKYMCExpr::VK_CSKY_TLSLE; + else if (Identifier.consume_back("@TLSLDM32")) + Kind = CSKYMCExpr::VK_CSKY_TLSLDM; + else if (Identifier.consume_back("@TLSLDO32")) + Kind = CSKYMCExpr::VK_CSKY_TLSLDO; + + MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); + + if (!Sym) + Sym = getContext().getOrCreateSymbol(Identifier); + + if (Sym->isVariable()) { + const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); + if (!isa<MCSymbolRefExpr>(V)) { + getLexer().UnLex(Tok); // Put back if it's not a bare symbol. + Error(getLoc(), "unknown symbol"); + return MatchOperand_ParseFail; + } + Res = V; + } else + Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); - MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); - const MCExpr *Res = - MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); + MCBinaryExpr::Opcode Opcode; + switch (getLexer().getKind()) { + default: + if (Kind != CSKYMCExpr::VK_CSKY_None) + Res = CSKYMCExpr::create(Res, Kind, getContext()); - if (Kind != CSKYMCExpr::VK_CSKY_None) - Res = CSKYMCExpr::create(Res, Kind, getContext()); + Operands.push_back(CSKYOperand::createImm(Res, S, E)); + return MatchOperand_Success; + case AsmToken::Plus: + Opcode = MCBinaryExpr::Add; + break; + case AsmToken::Minus: + Opcode = MCBinaryExpr::Sub; + break; + } + getLexer().Lex(); // eat + or - + + const MCExpr *Expr; + if (getParser().parseExpression(Expr)) { + Error(getLoc(), "unknown expression"); + return MatchOperand_ParseFail; + } + Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); Operands.push_back(CSKYOperand::createImm(Res, S, E)); return MatchOperand_Success; } +OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) { + SMLoc S = getLoc(); + SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); + const MCExpr *Res; + + if (getLexer().getKind() != AsmToken::LBrac) + return MatchOperand_NoMatch; + + getLexer().Lex(); // Eat '['. + + if (getLexer().getKind() != AsmToken::Identifier) { + const MCExpr *Expr; + if (getParser().parseExpression(Expr)) { + Error(getLoc(), "unknown expression"); + return MatchOperand_ParseFail; + } + + if (getLexer().getKind() != AsmToken::RBrac) { + Error(getLoc(), "expected ]"); + return MatchOperand_ParseFail; + } + + getLexer().Lex(); // Eat ']'. + + Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); + return MatchOperand_Success; + } + + AsmToken Tok = getLexer().getTok(); + StringRef Identifier; + + if (getParser().parseIdentifier(Identifier)) { + Error(getLoc(), "unknown identifier " + Identifier); + return MatchOperand_ParseFail; + } + + CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None; + if (Identifier.consume_back("@GOT")) + Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4; + else if (Identifier.consume_back("@PLT")) + Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4; + + MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); + + if (!Sym) + Sym = getContext().getOrCreateSymbol(Identifier); + + if (Sym->isVariable()) { + const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); + if (!isa<MCSymbolRefExpr>(V)) { + getLexer().UnLex(Tok); // Put back if it's not a bare symbol. + Error(getLoc(), "unknown symbol"); + return MatchOperand_ParseFail; + } + Res = V; + } else { + Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); + } + + MCBinaryExpr::Opcode Opcode; + switch (getLexer().getKind()) { + default: + Error(getLoc(), "unknown symbol"); + return MatchOperand_ParseFail; + case AsmToken::RBrac: + + getLexer().Lex(); // Eat ']'. + + if (Kind != CSKYMCExpr::VK_CSKY_None) + Res = CSKYMCExpr::create(Res, Kind, getContext()); + + Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); + return MatchOperand_Success; + case AsmToken::Plus: + Opcode = MCBinaryExpr::Add; + break; + case AsmToken::Minus: + Opcode = MCBinaryExpr::Sub; + break; + } + + getLexer().Lex(); // eat + or - + + const MCExpr *Expr; + if (getParser().parseExpression(Expr)) { + Error(getLoc(), "unknown expression"); + return MatchOperand_ParseFail; + } + + if (getLexer().getKind() != AsmToken::RBrac) { + Error(getLoc(), "expected ']'"); + return MatchOperand_ParseFail; + } + + getLexer().Lex(); // Eat ']'. + + Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); + Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); + return MatchOperand_Success; +} + OperandMatchResultTy CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) { SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); + const MCExpr *Res; if (getLexer().getKind() != AsmToken::LBrac) return MatchOperand_NoMatch; getLexer().Lex(); // Eat '['. - if (getLexer().getKind() != AsmToken::Identifier) - return MatchOperand_NoMatch; + if (getLexer().getKind() != AsmToken::Identifier) { + const MCExpr *Expr; + if (getParser().parseExpression(Expr)) { + Error(getLoc(), "unknown expression"); + return MatchOperand_ParseFail; + } + + if (getLexer().getKind() != AsmToken::RBrac) { + Error(getLoc(), "expected ']'"); + return MatchOperand_ParseFail; + } + + getLexer().Lex(); // Eat ']'. + + Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E)); + return MatchOperand_Success; + } + AsmToken Tok = getLexer().getTok(); StringRef Identifier; - if (getParser().parseIdentifier(Identifier)) + + if (getParser().parseIdentifier(Identifier)) { + Error(getLoc(), "unknown identifier"); return MatchOperand_ParseFail; + } - if (getLexer().getKind() != AsmToken::RBrac) - return MatchOperand_NoMatch; + MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier); + + if (!Sym) + Sym = getContext().getOrCreateSymbol(Identifier); + + if (Sym->isVariable()) { + const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); + if (!isa<MCSymbolRefExpr>(V)) { + getLexer().UnLex(Tok); // Put back if it's not a bare symbol. + Error(getLoc(), "unknown symbol"); + return MatchOperand_ParseFail; + } + Res = V; + } else { + Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); + } + + MCBinaryExpr::Opcode Opcode; + switch (getLexer().getKind()) { + default: + Error(getLoc(), "unknown symbol"); + return MatchOperand_ParseFail; + case AsmToken::RBrac: + + getLexer().Lex(); // Eat ']'. + + Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); + return MatchOperand_Success; + case AsmToken::Plus: + Opcode = MCBinaryExpr::Add; + break; + case AsmToken::Minus: + Opcode = MCBinaryExpr::Sub; + break; + } + + getLexer().Lex(); // eat + or - + + const MCExpr *Expr; + if (getParser().parseExpression(Expr)) { + Error(getLoc(), "unknown expression"); + return MatchOperand_ParseFail; + } + + if (getLexer().getKind() != AsmToken::RBrac) { + Error(getLoc(), "expected ']'"); + return MatchOperand_ParseFail; + } getLexer().Lex(); // Eat ']'. - MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); - const MCExpr *Res = - MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); - Operands.push_back(CSKYOperand::createImm(Res, S, E)); + Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); + Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E)); + return MatchOperand_Success; +} + +OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) { + SMLoc S = getLoc(); + SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); + + unsigned Flag = 0; + + while (getLexer().isNot(AsmToken::EndOfStatement)) { + StringRef Identifier; + if (getParser().parseIdentifier(Identifier)) { + Error(getLoc(), "unknown identifier " + Identifier); + return MatchOperand_ParseFail; + } + + if (Identifier == "sie") + Flag = (1 << 4) | Flag; + else if (Identifier == "ee") + Flag = (1 << 3) | Flag; + else if (Identifier == "ie") + Flag = (1 << 2) | Flag; + else if (Identifier == "fe") + Flag = (1 << 1) | Flag; + else if (Identifier == "af") + Flag = (1 << 0) | Flag; + else { + Error(getLoc(), "expected " + Identifier); + return MatchOperand_ParseFail; + } + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + if (getLexer().is(AsmToken::Comma)) { + getLexer().Lex(); // eat ',' + } else { + Error(getLoc(), "expected ,"); + return MatchOperand_ParseFail; + } + } + + Operands.push_back( + CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E)); + return MatchOperand_Success; +} + +OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) { + SMLoc S = getLoc(); + + if (parseRegister(Operands) != MatchOperand_Success) + return MatchOperand_NoMatch; + + auto Ry = Operands.back()->getReg(); + Operands.pop_back(); + + if (getLexer().isNot(AsmToken::Minus)) { + Error(getLoc(), "expected '-'"); + return MatchOperand_ParseFail; + } + + getLexer().Lex(); // eat '-' + + if (parseRegister(Operands) != MatchOperand_Success) { + Error(getLoc(), "invalid register"); + return MatchOperand_ParseFail; + } + + auto Rz = Operands.back()->getReg(); + Operands.pop_back(); + + Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S)); + return MatchOperand_Success; +} + +OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) { + SMLoc S = getLoc(); + + SmallVector<unsigned, 4> reglist; + + while (true) { + + if (parseRegister(Operands) != MatchOperand_Success) { + Error(getLoc(), "invalid register"); + return MatchOperand_ParseFail; + } + + auto Ry = Operands.back()->getReg(); + Operands.pop_back(); + + if (getLexer().is(AsmToken::Minus)) { + getLexer().Lex(); // eat '-' + + if (parseRegister(Operands) != MatchOperand_Success) { + Error(getLoc(), "invalid register"); + return MatchOperand_ParseFail; + } + + auto Rz = Operands.back()->getReg(); + Operands.pop_back(); + + reglist.push_back(Ry); + reglist.push_back(Rz); + + if (getLexer().is(AsmToken::Comma)) + getLexer().Lex(); // eat ',' + else if (getLexer().is(AsmToken::EndOfStatement)) + break; + + } else if (getLexer().is(AsmToken::Comma)) { + reglist.push_back(Ry); + reglist.push_back(Ry); + + getLexer().Lex(); // eat ',' + } else if (getLexer().is(AsmToken::EndOfStatement)) { + reglist.push_back(Ry); + reglist.push_back(Ry); + break; + } else { + Error(getLoc(), "invalid register list"); + return MatchOperand_ParseFail; + } + } + + Operands.push_back(CSKYOperand::createRegList(reglist, S)); return MatchOperand_Success; } @@ -638,7 +1413,7 @@ OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo, StringRef Name = getLexer().getTok().getIdentifier(); - if (matchRegisterNameHelper((MCRegister &)RegNo, Name)) + if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) return MatchOperand_NoMatch; getParser().Lex(); // Eat identifier token. diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.h new file mode 100644 index 000000000000..357b1e96e606 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.h @@ -0,0 +1,27 @@ +//===-- CSKY.h - Top-level interface for CSKY--------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points for global functions defined in the LLVM +// CSKY back-end. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKY_H +#define LLVM_LIB_TARGET_CSKY_CSKY_H + +#include "llvm/Target/TargetMachine.h" + +namespace llvm { +class CSKYTargetMachine; +class FunctionPass; + +FunctionPass *createCSKYISelDag(CSKYTargetMachine &TM); + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKY_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.td b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.td index 854a8b5f22a2..e26781ca6aa1 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.td +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.td @@ -9,10 +9,97 @@ include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// +// CSKY subtarget features and instruction predicates. +//===----------------------------------------------------------------------===// + +def FeatureBTST16 : SubtargetFeature<"btst16", "HasBTST16", "true", + "Use the 16-bit btsti instruction">; +def HasBTST16 : Predicate<"Subtarget->hasBTST16()">, + AssemblerPredicate<(all_of FeatureBTST16), + "Use the 16-bit btsti instruction">; + +// Atomic Support +def FeatureExtendLrw : SubtargetFeature<"elrw", "HasExtendLrw", "true", + "Use the extend LRW instruction">; +def HasExtendLrw : Predicate<"Subtarget->hasExtendLrw()">, + AssemblerPredicate<(all_of FeatureExtendLrw), + "Use the extend LRW instruction">; + +def FeatureJAVA + : SubtargetFeature<"java", "HasJAVA", "true", "Enable java instructions">; +def HasJAVA : Predicate<"Subtarget->hasJAVA()">, + AssemblerPredicate<(all_of FeatureJAVA), + "Enable java instructions">; + +def FeatureDoloop : SubtargetFeature<"doloop", "HasDoloop", "true", + "Enable doloop instructions">; +def HasDoloop : Predicate<"Subtarget->hasDoloop()">, + AssemblerPredicate<(all_of FeatureDoloop), + "Enable doloop instructions">; + +def HasE1 + : SubtargetFeature<"e1", "HasE1", "true", "Support CSKY e1 instructions", + [FeatureExtendLrw]>; +def iHasE1 : Predicate<"Subtarget->hasE1()">, + AssemblerPredicate<(all_of HasE1), + "Support CSKY e1 instructions">; + +def HasE2 + : SubtargetFeature<"e2", "HasE2", "true", "Support CSKY e2 instructions", + [HasE1]>; +def iHasE2 : Predicate<"Subtarget->hasE2()">, + AssemblerPredicate<(all_of HasE2), + "Support CSKY e2 instructions">; + +def Has2E3 : SubtargetFeature<"2e3", "Has2E3", "true", + "Support CSKY 2e3 instructions", [HasE2]>; +def iHas2E3 : Predicate<"Subtarget->has2E3()">, + AssemblerPredicate<(all_of Has2E3), + "Support CSKY 2e3 instructions">; + +def Has3E3r1 : SubtargetFeature<"3e3r1", "Has3E3r1", "true", + "Support CSKY 3e3r1 instructions">; +def iHas3E3r1 : Predicate<"Subtarget->has3E3r1()">, + AssemblerPredicate<(all_of Has3E3r1), + "Support CSKY 3e3r1 instructions">; + +def Has3r2E3r3 + : SubtargetFeature<"3e3r3", "Has3r2E3r3", "true", + "Support CSKY 3e3r3 instructions", [FeatureDoloop]>; +def iHas3r2E3r3 : Predicate<"Subtarget->has3r2E3r3()">, + AssemblerPredicate<(all_of Has3r2E3r3), + "Support CSKY 3e3r3 instructions">; + +def Has3E7 : SubtargetFeature<"3e7", "Has3E7", "true", + "Support CSKY 3e7 instructions", [Has2E3]>; +def iHas3E7 : Predicate<"Subtarget->has3E7()">, + AssemblerPredicate<(all_of Has3E7), + "Support CSKY 3e7 instructions">; + +def HasMP1E2 : SubtargetFeature<"mp1e2", "HasMP1E2", "true", + "Support CSKY mp1e2 instructions", [Has3E7]>; +def iHasMP1E2 : Predicate<"Subtarget->hasMP1E2()">, + AssemblerPredicate<(all_of HasMP1E2), + "Support CSKY mp1e2 instructions">; + +def Has7E10 : SubtargetFeature<"7e10", "Has7E10", "true", + "Support CSKY 7e10 instructions", [Has3E7]>; +def iHas7E10 : Predicate<"Subtarget->has7E10()">, + AssemblerPredicate<(all_of Has7E10), + "Support CSKY 7e10 instructions">; + +def Has10E60 : SubtargetFeature<"10e60", "Has10E60", "true", + "Support CSKY 10e60 instructions", [Has7E10]>; +def iHas10E60 : Predicate<"Subtarget->has10E60()">, + AssemblerPredicate<(all_of Has10E60), + "Support CSKY 10e60 instructions">; + +//===----------------------------------------------------------------------===// // Registers, calling conventions, instruction descriptions. //===----------------------------------------------------------------------===// include "CSKYRegisterInfo.td" +include "CSKYCallingConv.td" include "CSKYInstrInfo.td" //===----------------------------------------------------------------------===// diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp new file mode 100644 index 000000000000..1c38c5d1fde6 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp @@ -0,0 +1,58 @@ +//===-- CSKYAsmPrinter.cpp - CSKY LLVM assembly writer --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to the CSKY assembly language. +// +//===----------------------------------------------------------------------===// +#include "CSKYAsmPrinter.h" +#include "CSKY.h" +#include "CSKYTargetMachine.h" +#include "MCTargetDesc/CSKYInstPrinter.h" +#include "MCTargetDesc/CSKYMCExpr.h" +#include "TargetInfo/CSKYTargetInfo.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/TargetRegistry.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-asm-printer" + +CSKYAsmPrinter::CSKYAsmPrinter(llvm::TargetMachine &TM, + std::unique_ptr<llvm::MCStreamer> Streamer) + : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this) {} + +bool CSKYAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + Subtarget = &MF.getSubtarget<CSKYSubtarget>(); + return AsmPrinter::runOnMachineFunction(MF); +} + +// Simple pseudo-instructions have their lowering (with expansion to real +// instructions) auto-generated. +#include "CSKYGenMCPseudoLowering.inc" + +void CSKYAsmPrinter::emitInstruction(const MachineInstr *MI) { + // Do any auto-generated pseudo lowerings. + if (emitPseudoExpansionLowering(*OutStreamer, MI)) + return; + + MCInst TmpInst; + MCInstLowering.Lower(MI, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); +} + +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmPrinter() { + RegisterAsmPrinter<CSKYAsmPrinter> X(getTheCSKYTarget()); +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.h new file mode 100644 index 000000000000..f0f5d8657c04 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.h @@ -0,0 +1,40 @@ +//===-- CSKYAsmPrinter.h - CSKY implementation of AsmPrinter ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYASMPRINTER_H +#define LLVM_LIB_TARGET_CSKY_CSKYASMPRINTER_H + +#include "CSKYMCInstLower.h" +#include "CSKYSubtarget.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/MC/MCDirectives.h" + +namespace llvm { +class LLVM_LIBRARY_VISIBILITY CSKYAsmPrinter : public AsmPrinter { + CSKYMCInstLower MCInstLowering; + + const CSKYSubtarget *Subtarget; + +public: + explicit CSKYAsmPrinter(TargetMachine &TM, + std::unique_ptr<MCStreamer> Streamer); + + StringRef getPassName() const override { return "CSKY Assembly Printer"; } + + /// tblgen'erated driver function for lowering simple MI->MC + /// pseudo instructions. + bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, + const MachineInstr *MI); + + void emitInstruction(const MachineInstr *MI) override; + + bool runOnMachineFunction(MachineFunction &MF) override; +}; +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYASMPRINTER_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.h new file mode 100644 index 000000000000..f1048f86264b --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.h @@ -0,0 +1,63 @@ +//=== CSKYCallingConv.h - CSKY Custom Calling Convention Routines -*-C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the custom routines for the CSKY Calling Convention that +// aren't done by tablegen. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYCALLINGCONV_H +#define LLVM_LIB_TARGET_CSKY_CSKYCALLINGCONV_H + +#include "CSKY.h" +#include "CSKYSubtarget.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/IR/CallingConv.h" + +namespace llvm { + +static bool CC_CSKY_ABIV2_SOFT_64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, + CCValAssign::LocInfo &LocInfo, + ISD::ArgFlagsTy &ArgFlags, CCState &State) { + + static const MCPhysReg ArgGPRs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3}; + Register Reg = State.AllocateReg(ArgGPRs); + LocVT = MVT::i32; + if (!Reg) { + unsigned StackOffset = State.AllocateStack(8, Align(4)); + State.addLoc( + CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo)); + return true; + } + if (!State.AllocateReg(ArgGPRs)) + State.AllocateStack(4, Align(4)); + State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); + return true; +} + +static bool Ret_CSKY_ABIV2_SOFT_64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, + CCValAssign::LocInfo &LocInfo, + ISD::ArgFlagsTy &ArgFlags, CCState &State) { + + static const MCPhysReg ArgGPRs[] = {CSKY::R0, CSKY::R1}; + Register Reg = State.AllocateReg(ArgGPRs); + LocVT = MVT::i32; + if (!Reg) + return false; + + if (!State.AllocateReg(ArgGPRs)) + return false; + + State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); + return true; +} + +} // namespace llvm + +#endif diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.td b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.td new file mode 100644 index 000000000000..87e2e6b9dc31 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.td @@ -0,0 +1,82 @@ +//===-- CSKYCallingConv.td - Calling Conventions CSKY ----*- tablegen -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This describes the calling conventions for the CSKY architecture. +// +//===----------------------------------------------------------------------===// + +def CSR_I32 : CalleeSavedRegs<(add R8, R15, (sequence "R%u", 4, 7), + (sequence "R%u", 9, 11), (sequence "R%u", 16, 17), R28)>; +def CSR_GPR_FPR32 : CalleeSavedRegs<(add CSR_I32, (sequence "F%u_32", 8, 15))>; +def CSR_GPR_FPR64 : CalleeSavedRegs<(add CSR_I32, + (sequence "F%u_64", 8, 15))>; + +// Interrupt handler needs to save/restore all registers that are used, +// both Caller and Callee saved registers. +def CSR_GPR_ISR : CalleeSavedRegs<(add R8, R15, + (sequence "R%u", 0, 3), + (sequence "R%u", 4, 7), + (sequence "R%u", 9, 13), + (sequence "R%u", 16, 31))>; + +def CSR_GPR_FPR32_ISR: CalleeSavedRegs<(add CSR_GPR_ISR, + (sequence "F%u_32", 0, 15))>; +def CSR_GPR_FPR64_ISR: CalleeSavedRegs<(add CSR_GPR_ISR, + (sequence "F%u_64", 0, 15))>; + +def CSR_GPR_FPR32v3_ISR: CalleeSavedRegs<(add CSR_GPR_FPR32_ISR, + (sequence "F%u_32", 16, 31))>; +def CSR_GPR_FPR64v3_ISR: CalleeSavedRegs<(add CSR_GPR_FPR64_ISR, + (sequence "F%u_64", 16, 31))>; + +// Needed for implementation of CSKYRegisterInfo::getNoPreservedMask() +def CSR_NoRegs : CalleeSavedRegs<(add)>; + +def CC_CSKY_ABIV2_SOFT : CallingConv<[ + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[v2i16, v4i8], CCAssignToStack<4, 4>>, + CCIfType<[i8, i16], CCPromoteToType<i32>>, + CCIfType<[f32], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[f32], CCAssignToStack<4, 4>>, + CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[i32], CCAssignToStack<4, 4>>, + CCIfType<[f64], CCCustom<"CC_CSKY_ABIV2_SOFT_64">>, + CCIfType<[f64], CCAssignToStack<8, 4>> +]>; + +def RetCC_CSKY_ABIV2_SOFT : CallingConv<[ + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1]>>, + CCIfType<[i8, i16], CCPromoteToType<i32>>, + CCIfType<[f32], CCBitConvertToType<i32>>, + CCIfType<[i32], CCAssignToReg<[R0, R1]>>, + CCIfType<[f64], CCCustom<"Ret_CSKY_ABIV2_SOFT_64">> +]>; + +def CC_CSKY_ABIV2_FP : CallingConv<[ + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[v2i16, v4i8], CCAssignToStack<4, 4>>, + CCIfType<[i8, i16], CCPromoteToType<i32>>, + CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[i32], CCAssignToStack<4, 4>>, + CCIfType<[f32], CCAssignToReg<[F0_32, F1_32, F2_32, F3_32]>>, + CCIfType<[f32], CCAssignToStack<4, 4>>, + CCIfType<[f64], CCAssignToReg<[F0_64, F1_64, F2_64, F3_64]>>, + CCIfType<[f64], CCAssignToStack<8, 4>> +]>; + +def RetCC_CSKY_ABIV2_FP : CallingConv<[ + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1]>>, + CCIfType<[i8, i16], CCPromoteToType<i32>>, + CCIfType<[i32], CCAssignToReg<[R0, R1]>>, + CCIfType<[f32], CCAssignToReg<[F0_32]>>, + CCIfType<[f64], CCAssignToReg<[F0_64]>> +]>;
\ No newline at end of file diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp new file mode 100644 index 000000000000..9b22c95cfe21 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp @@ -0,0 +1,57 @@ +//===-- CSKYFrameLowering.cpp - CSKY Frame Information ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYFrameLowering.h" +#include "CSKYSubtarget.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/MC/MCDwarf.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-frame-lowering" + +// Returns the register used to hold the frame pointer. +static Register getFPReg(const CSKYSubtarget &STI) { return CSKY::R8; } + +// To avoid the BP value clobbered by a function call, we need to choose a +// callee saved register to save the value. +static Register getBPReg(const CSKYSubtarget &STI) { return CSKY::R7; } + +bool CSKYFrameLowering::hasFP(const MachineFunction &MF) const { + const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); + + const MachineFrameInfo &MFI = MF.getFrameInfo(); + return MF.getTarget().Options.DisableFramePointerElim(MF) || + RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() || + MFI.isFrameAddressTaken(); +} + +bool CSKYFrameLowering::hasBP(const MachineFunction &MF) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + + return MFI.hasVarSizedObjects(); +} + +void CSKYFrameLowering::emitPrologue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + // FIXME: Implement this when we have function calls +} + +void CSKYFrameLowering::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + // FIXME: Implement this when we have function calls +}
\ No newline at end of file diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.h new file mode 100644 index 000000000000..49921a1866bc --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.h @@ -0,0 +1,38 @@ +//===-- CSKYFrameLowering.h - Define frame lowering for CSKY -*- C++ -*--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class implements CSKY-specific bits of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYFRAMELOWERING_H +#define LLVM_LIB_TARGET_CSKY_CSKYFRAMELOWERING_H + +#include "llvm/CodeGen/TargetFrameLowering.h" + +namespace llvm { +class CSKYSubtarget; + +class CSKYFrameLowering : public TargetFrameLowering { + const CSKYSubtarget &STI; + +public: + explicit CSKYFrameLowering(const CSKYSubtarget &STI) + : TargetFrameLowering(StackGrowsDown, + /*StackAlignment=*/Align(4), + /*LocalAreaOffset=*/0), + STI(STI) {} + + void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + + bool hasFP(const MachineFunction &MF) const override; + bool hasBP(const MachineFunction &MF) const; +}; +} // namespace llvm +#endif diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp new file mode 100644 index 000000000000..fc9ef8bfd9d9 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp @@ -0,0 +1,75 @@ +//===-- CSKYISelDAGToDAG.cpp - A dag to dag inst selector for CSKY---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines an instruction selector for the CSKY target. +// +//===----------------------------------------------------------------------===// + +#include "CSKY.h" +#include "CSKYSubtarget.h" +#include "CSKYTargetMachine.h" +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-isel" + +namespace { +class CSKYDAGToDAGISel : public SelectionDAGISel { + const CSKYSubtarget *Subtarget; + +public: + explicit CSKYDAGToDAGISel(CSKYTargetMachine &TM) : SelectionDAGISel(TM) {} + + StringRef getPassName() const override { + return "CSKY DAG->DAG Pattern Instruction Selection"; + } + + bool runOnMachineFunction(MachineFunction &MF) override { + // Reset the subtarget each time through. + Subtarget = &MF.getSubtarget<CSKYSubtarget>(); + SelectionDAGISel::runOnMachineFunction(MF); + return true; + } + + void Select(SDNode *N) override; + +#include "CSKYGenDAGISel.inc" +}; +} // namespace + +void CSKYDAGToDAGISel::Select(SDNode *N) { + // If we have a custom node, we have already selected + if (N->isMachineOpcode()) { + LLVM_DEBUG(dbgs() << "== "; N->dump(CurDAG); dbgs() << "\n"); + N->setNodeId(-1); + return; + } + + SDLoc Dl(N); + unsigned Opcode = N->getOpcode(); + bool IsSelected = false; + + switch (Opcode) { + default: + break; + // FIXME: Add selection nodes needed later. + } + + if (IsSelected) + return; + + // Select the default instruction. + SelectCode(N); +} + +FunctionPass *llvm::createCSKYISelDag(CSKYTargetMachine &TM) { + return new CSKYDAGToDAGISel(TM); +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.cpp new file mode 100644 index 000000000000..ac6d069e592c --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.cpp @@ -0,0 +1,346 @@ +//===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that CSKY uses to lower LLVM code into a +// selection DAG. +// +//===----------------------------------------------------------------------===// + +#include "CSKYISelLowering.h" +#include "CSKYCallingConv.h" +#include "CSKYMachineFunctionInfo.h" +#include "CSKYRegisterInfo.h" +#include "CSKYSubtarget.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-isel-lowering" + +STATISTIC(NumTailCalls, "Number of tail calls"); + +#include "CSKYGenCallingConv.inc" + +static const MCPhysReg GPRArgRegs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3}; + +CSKYTargetLowering::CSKYTargetLowering(const TargetMachine &TM, + const CSKYSubtarget &STI) + : TargetLowering(TM), Subtarget(STI) { + // Register Class + addRegisterClass(MVT::i32, &CSKY::GPRRegClass); + + // Compute derived properties from the register classes. + computeRegisterProperties(STI.getRegisterInfo()); + + setBooleanContents(UndefinedBooleanContent); + setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); + + // TODO: Add atomic support fully. + setMaxAtomicSizeInBitsSupported(0); + + setStackPointerRegisterToSaveRestore(CSKY::R14); + const Align FunctionAlignment(2); + setMinFunctionAlignment(FunctionAlignment); + setSchedulingPreference(Sched::Source); +} + +EVT CSKYTargetLowering::getSetCCResultType(const DataLayout &DL, + LLVMContext &Context, EVT VT) const { + if (!VT.isVector()) + return MVT::i32; + + return VT.changeVectorElementTypeToInteger(); +} + +static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, + const CCValAssign &VA, const SDLoc &DL) { + EVT LocVT = VA.getLocVT(); + + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unexpected CCValAssign::LocInfo"); + case CCValAssign::Full: + break; + case CCValAssign::BCvt: + Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val); + break; + } + return Val; +} + +static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, + const CCValAssign &VA, const SDLoc &DL) { + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unexpected CCValAssign::LocInfo"); + case CCValAssign::Full: + break; + case CCValAssign::BCvt: + Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val); + break; + } + return Val; +} + +static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget, + SelectionDAG &DAG, SDValue Chain, + const CCValAssign &VA, const SDLoc &DL) { + MachineFunction &MF = DAG.getMachineFunction(); + MachineRegisterInfo &RegInfo = MF.getRegInfo(); + EVT LocVT = VA.getLocVT(); + SDValue Val; + const TargetRegisterClass *RC; + + switch (LocVT.getSimpleVT().SimpleTy) { + default: + llvm_unreachable("Unexpected register type"); + case MVT::i32: + RC = &CSKY::GPRRegClass; + break; + } + + Register VReg = RegInfo.createVirtualRegister(RC); + RegInfo.addLiveIn(VA.getLocReg(), VReg); + Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT); + + return convertLocVTToValVT(DAG, Val, VA, DL); +} + +static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain, + const CCValAssign &VA, const SDLoc &DL) { + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + EVT LocVT = VA.getLocVT(); + EVT ValVT = VA.getValVT(); + EVT PtrVT = MVT::getIntegerVT(DAG.getDataLayout().getPointerSizeInBits(0)); + int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8, + VA.getLocMemOffset(), /*Immutable=*/true); + SDValue FIN = DAG.getFrameIndex(FI, PtrVT); + SDValue Val; + + ISD::LoadExtType ExtType; + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unexpected CCValAssign::LocInfo"); + case CCValAssign::Full: + case CCValAssign::BCvt: + ExtType = ISD::NON_EXTLOAD; + break; + } + Val = DAG.getExtLoad( + ExtType, DL, LocVT, Chain, FIN, + MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), ValVT); + return Val; +} + +// Transform physical registers into virtual registers. +SDValue CSKYTargetLowering::LowerFormalArguments( + SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL, + SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { + + switch (CallConv) { + default: + report_fatal_error("Unsupported calling convention"); + case CallingConv::C: + case CallingConv::Fast: + break; + } + + MachineFunction &MF = DAG.getMachineFunction(); + + // Used with vargs to acumulate store chains. + std::vector<SDValue> OutChains; + + // Assign locations to all of the incoming arguments. + SmallVector<CCValAssign, 16> ArgLocs; + CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); + + CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg)); + + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + CCValAssign &VA = ArgLocs[i]; + SDValue ArgValue; + + if (VA.isRegLoc()) + ArgValue = unpackFromRegLoc(Subtarget, DAG, Chain, VA, DL); + else + ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL); + + InVals.push_back(ArgValue); + } + + if (IsVarArg) { + const unsigned XLenInBytes = 4; + const MVT XLenVT = MVT::i32; + + ArrayRef<MCPhysReg> ArgRegs = makeArrayRef(GPRArgRegs); + unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs); + const TargetRegisterClass *RC = &CSKY::GPRRegClass; + MachineFrameInfo &MFI = MF.getFrameInfo(); + MachineRegisterInfo &RegInfo = MF.getRegInfo(); + CSKYMachineFunctionInfo *CSKYFI = MF.getInfo<CSKYMachineFunctionInfo>(); + + // Offset of the first variable argument from stack pointer, and size of + // the vararg save area. For now, the varargs save area is either zero or + // large enough to hold a0-a4. + int VaArgOffset, VarArgsSaveSize; + + // If all registers are allocated, then all varargs must be passed on the + // stack and we don't need to save any argregs. + if (ArgRegs.size() == Idx) { + VaArgOffset = CCInfo.getNextStackOffset(); + VarArgsSaveSize = 0; + } else { + VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx); + VaArgOffset = -VarArgsSaveSize; + } + + // Record the frame index of the first variable argument + // which is a value necessary to VASTART. + int FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true); + CSKYFI->setVarArgsFrameIndex(FI); + + // Copy the integer registers that may have been used for passing varargs + // to the vararg save area. + for (unsigned I = Idx; I < ArgRegs.size(); + ++I, VaArgOffset += XLenInBytes) { + const Register Reg = RegInfo.createVirtualRegister(RC); + RegInfo.addLiveIn(ArgRegs[I], Reg); + SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, XLenVT); + FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true); + SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); + SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff, + MachinePointerInfo::getFixedStack(MF, FI)); + cast<StoreSDNode>(Store.getNode()) + ->getMemOperand() + ->setValue((Value *)nullptr); + OutChains.push_back(Store); + } + CSKYFI->setVarArgsSaveSize(VarArgsSaveSize); + } + + // All stores are grouped in one node to allow the matching between + // the size of Ins and InVals. This only happens for vararg functions. + if (!OutChains.empty()) { + OutChains.push_back(Chain); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); + } + + return Chain; +} + +bool CSKYTargetLowering::CanLowerReturn( + CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { + SmallVector<CCValAssign, 16> CSKYLocs; + CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context); + return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg)); +} + +SDValue +CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<SDValue> &OutVals, + const SDLoc &DL, SelectionDAG &DAG) const { + // Stores the assignment of the return value to a location. + SmallVector<CCValAssign, 16> CSKYLocs; + + // Info about the registers and stack slot. + CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), CSKYLocs, + *DAG.getContext()); + CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg)); + + SDValue Glue; + SmallVector<SDValue, 4> RetOps(1, Chain); + + // Copy the result values into the output registers. + for (unsigned i = 0, e = CSKYLocs.size(); i < e; ++i) { + SDValue Val = OutVals[i]; + CCValAssign &VA = CSKYLocs[i]; + assert(VA.isRegLoc() && "Can only return in registers!"); + + bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64; + + if (IsF64OnCSKY) { + + assert(VA.isRegLoc() && "Expected return via registers"); + SDValue Split64 = DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL, + DAG.getVTList(MVT::i32, MVT::i32), Val); + SDValue Lo = Split64.getValue(0); + SDValue Hi = Split64.getValue(1); + + Register RegLo = VA.getLocReg(); + assert(RegLo < CSKY::R31 && "Invalid register pair"); + Register RegHi = RegLo + 1; + + Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue); + Glue = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(RegLo, MVT::i32)); + Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue); + Glue = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(RegHi, MVT::i32)); + } else { + // Handle a 'normal' return. + Val = convertValVTToLocVT(DAG, Val, VA, DL); + Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue); + + // Guarantee that all emitted copies are stuck together. + Glue = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); + } + } + + RetOps[0] = Chain; // Update chain. + + // Add the glue node if we have it. + if (Glue.getNode()) { + RetOps.push_back(Glue); + } + + // Interrupt service routines use different return instructions. + if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt")) + return DAG.getNode(CSKYISD::NIR, DL, MVT::Other, RetOps); + + return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps); +} + +CCAssignFn *CSKYTargetLowering::CCAssignFnForReturn(CallingConv::ID CC, + bool IsVarArg) const { + if (IsVarArg || !Subtarget.useHardFloatABI()) + return RetCC_CSKY_ABIV2_SOFT; + else + return RetCC_CSKY_ABIV2_FP; +} + +CCAssignFn *CSKYTargetLowering::CCAssignFnForCall(CallingConv::ID CC, + bool IsVarArg) const { + if (IsVarArg || !Subtarget.useHardFloatABI()) + return CC_CSKY_ABIV2_SOFT; + else + return CC_CSKY_ABIV2_FP; +} + +const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const { + switch (Opcode) { + default: + llvm_unreachable("unknown CSKYISD node"); + case CSKYISD::NIE: + return "CSKYISD::NIE"; + case CSKYISD::NIR: + return "CSKYISD::NIR"; + case CSKYISD::RET: + return "CSKYISD::RET"; + case CSKYISD::BITCAST_TO_LOHI: + return "CSKYISD::BITCAST_TO_LOHI"; + } +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.h new file mode 100644 index 000000000000..7557c11f50a8 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.h @@ -0,0 +1,69 @@ +//===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that CSKY uses to lower LLVM code into a +// selection DAG. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H +#define LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H + +#include "MCTargetDesc/CSKYBaseInfo.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/TargetLowering.h" + +namespace llvm { +class CSKYSubtarget; + +namespace CSKYISD { +enum NodeType : unsigned { + FIRST_NUMBER = ISD::BUILTIN_OP_END, + NIE, + NIR, + RET, + BITCAST_TO_LOHI +}; +} + +class CSKYTargetLowering : public TargetLowering { + const CSKYSubtarget &Subtarget; + +public: + explicit CSKYTargetLowering(const TargetMachine &TM, + const CSKYSubtarget &STI); + + EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, + EVT VT) const override; + +private: + SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + const SDLoc &DL, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) const override; + + bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, + bool IsVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + LLVMContext &Context) const override; + + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, + SelectionDAG &DAG) const override; + + const char *getTargetNodeName(unsigned Opcode) const override; + + CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; + CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg) const; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats.td b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats.td index dd71b693bbbb..9b6ef9ca23db 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats.td +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats.td @@ -24,7 +24,7 @@ class CSKYInst<AddrMode am, int sz, dag outs, dag ins, string asmstr, let Namespace = "CSKY"; int Size = sz; AddrMode AM = am; - + field bits<32> SoftFail = 0; let OutOperandList = outs; let InOperandList = ins; let AsmString = asmstr; @@ -46,6 +46,11 @@ class CSKY32Inst<AddrMode am, bits<6> opcode, dag outs, dag ins, string asmstr, let Inst{31 - 26} = opcode; } +class CSKY16Inst<AddrMode am, dag outs, dag ins, string asmstr, list<dag> pattern> + : CSKYInst<am, 2, outs, ins, asmstr, pattern> { + field bits<16> Inst; +} + // CSKY 32-bit instruction // Format< OP[6] | Offset[26] > // Instruction(1): bsr32 @@ -157,19 +162,7 @@ class I_16_RET<bits<5> sop, bits<5> pcode, string op, list<dag> pattern> let isTerminator = 1; let isReturn = 1; let isBarrier = 1; -} - -// Instructions(1): rte32 -class I_16_RET_I<bits<5> sop, bits<5> pcode, string op, list<dag> pattern> - : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), op, pattern> { - let Inst{25 - 21} = sop; - let Inst{20 - 16} = pcode; - let Inst{15 - 10} = 0x10; - let Inst{9 - 5} = 1; - let Inst{4 - 0} = 0; - let isTerminator = 1; - let isReturn = 1; - let isBarrier = 1; + let Uses = [ R15 ]; } // Format< OP[6] | SOP[5] | RX[5] | IMM16[16] > @@ -227,14 +220,27 @@ class I_LDST<AddrMode am, bits<6> opcode, bits<4> sop, dag outs, dag ins, let Inst{11 - 0} = imm12; } +class I_PLDR<AddrMode am, bits<6> opcode, bits<4> sop, dag outs, dag ins, + string op, list<dag> pattern> + : CSKY32Inst<am, opcode, outs, ins, !strconcat(op, "\t($rx, ${imm12})"), + pattern> { + bits<5> rx; + bits<12> imm12; + let Inst{25 - 21} = 0; + let Inst{20 - 16} = rx; + let Inst{15 - 12} = sop; + let Inst{11 - 0} = imm12; +} + + // Format< OP[6] | RZ[5] | RX[5] | SOP[4] | OFFSET[12] > -// Instructions(6): ld32.b, ld32.bs, ld32.h, ld32.hs, ld32.w, ld32.d +// Instructions(6): ld32.b, ld32.bs, ld32.h, ld32.hs, ld32.w class I_LD<AddrMode am, bits<4> sop, string op, Operand operand> : I_LDST<am, 0x36, sop, (outs GPR:$rz), (ins GPR:$rx, operand:$imm12), op, []>; // Format< OP[6] | RZ[5] | RX[5] | SOP[4] | OFFSET[12] > -// Instructions(4): st32.b, st32.h, st32.w, st32.d +// Instructions(4): st32.b, st32.h, st32.w class I_ST<AddrMode am, bits<4> sop, string op, Operand operand> : I_LDST<am, 0x37, sop, (outs), (ins GPR:$rz, GPR:$rx, operand:$imm12), op, []>; @@ -249,6 +255,8 @@ class I_12_PP<bits<5> sop, bits<5> pcode, dag outs, dag ins, string op> let Inst{20 - 16} = pcode; let Inst{15 - 12} = 0; let Inst{11 - 0} = regs; + let Uses = [R14]; + let Defs = [R14]; } // Format< OP[6] | RZ[5] | RX[5] | SOP[6] | PCODE[5] | IMM[5]> @@ -256,7 +264,7 @@ class I_12_PP<bits<5> sop, bits<5> pcode, dag outs, dag ins, string op> class I_5_ZX<bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType, list<dag> pattern> : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz), - (ins GPR:$false, GPR:$rx, ImmType:$imm5), + (ins CARRY:$cond, GPR:$false, GPR:$rx, ImmType:$imm5), !strconcat(op, "\t$rz, $rx, $imm5"), pattern> { bits<5> rz; bits<5> rx; @@ -272,9 +280,9 @@ class I_5_ZX<bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType, // Format< OP[6] | IMM[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5]> // Instructions(13): decgt32, declt32, decne32, lsli32, lslc32, lsri32 // lsrc32, asri32, asrc32, rotli32, xsr32, bclri32, bseti32 -class I_5_XZ<bits<6> sop, bits<5> pcode, string op, dag ins, dag outs, +class I_5_XZ<bits<6> sop, bits<5> pcode, string op, dag outs, dag ins, list<dag> pattern> - : CSKY32Inst<AddrModeNone, 0x31, ins, outs, + : CSKY32Inst<AddrModeNone, 0x31, outs, ins, !strconcat(op, "\t$rz, $rx, $imm5"), pattern> { bits<5> imm5; bits<5> rx; @@ -286,19 +294,107 @@ class I_5_XZ<bits<6> sop, bits<5> pcode, string op, dag ins, dag outs, let Inst{4 - 0} = rz; } +// mtcr32, mfcr32 +class I_5_XZ_CR<bits<6> sop, bits<5> pcode, string opStr, dag outs, dag ins, + list<dag> pattern> + : CSKY32Inst<AddrModeNone, 0x30, outs, ins, opStr, pattern> { + bits<5> sel; + bits<5> rx; + bits<5> cr; + let Inst{25 - 21} = sel; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = cr; +} + +// sync +class I_5_XZ_SYNC<bits<6> sop, bits<5> pcode, string opStr, bits<1> S, bits<1> I> + : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), opStr, []> { + let Inst{25 - 21} = 0; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; + let Inst{25} = S; + let Inst{21} = I; + +} + +// Priviledged Instructions +class I_5_XZ_PRIVI<bits<6> sop, bits<5> pcode, string opStr> + : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), opStr, []> { + let Inst{25 - 21} = 0; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; +} + +class I_CP<bits<4> sop, dag outs, dag ins, string opStr> + : CSKY32Inst<AddrModeNone, 0x3f, outs, ins, opStr, []> { + bits<5> cpid; + bits<12> usdef; + let Inst{25 - 21} = cpid; + let Inst{20 - 16} = 0; + let Inst{15 - 12} = sop; + let Inst{11 - 0} = usdef; +} + +class I_CPOP<dag outs, dag ins, string opStr> + : CSKY32Inst<AddrModeNone, 0x3f, outs, ins, opStr, []> { + bits<5> cpid; + bits<20> usdef; + let Inst{25 - 21} = cpid; + let Inst{20 - 16} = usdef{19-15}; + let Inst{15} = 1; + let Inst{14 - 0} = usdef{14-0}; +} + +class I_CP_Z<bits<4> sop, dag outs, dag ins, string opStr> + : CSKY32Inst<AddrModeNone, 0x3f, outs, ins, opStr, []> { + bits<5> cpid; + bits<12> usdef; + bits<5> rz; + + let Inst{25 - 21} = cpid; + let Inst{20 - 16} = rz; + let Inst{15 - 12} = sop; + let Inst{11 - 0} = usdef; +} + +class I_5_CACHE<bits<6> sop, bits<5> pcode, string opStr> + : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), opStr, []> { + let Inst{25 - 21} = pcode; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0; +} + +class I_5_X_CACHE<bits<6> sop, bits<5> pcode, string opStr> + : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins GPR:$rx), opStr #"\t$rx", []> { + bits<5> rx; + + let Inst{25 - 21} = pcode; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0; +} + // Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | IMM[5]> // Instructions(2): ldm32, (ldq32), stm32, (stq32) -class I_5_YX<bits<6> opcode, dag outs, dag ins, string op, list<dag> pattern, - bits<5> imm5> - : CSKY32Inst<AddrModeNone, opcode, outs, ins, - op #"\t${ry}, (${rx}), " #!cast<int>(imm5), pattern> { +class I_5_YX<bits<6> opcode, bits<6> sop, dag outs, dag ins, string opStr, list<dag> pattern> + : CSKY32Inst<AddrModeNone, opcode, outs, ins, opStr, pattern> { + bits<10> regs; bits<5> rx; - bits<5> ry; - let Inst{25 - 21} = ry; // ry + + let Inst{25 - 21} = regs{9 - 5}; // ry let Inst{20 - 16} = rx; - let Inst{15 - 10} = 0b000111; + let Inst{15 - 10} = sop; let Inst{9 - 5} = 0b00001; - let Inst{4 - 0} = imm5{4 - 0}; // imm5 + let Inst{4 - 0} = regs{4 - 0}; // imm5 } // Format< OP[6] | LSB[5] | RX[5] | SOP[6] | MSB[5] | RZ[5]> @@ -317,14 +413,33 @@ class I_5_XZ_U<bits<6> sop, dag outs, dag ins, string op, list<dag> pattern> let Inst{4 - 0} = rz; } -// sextb, sexth -class I_5_XZ_US<bits<6> sop, string op, SDNode opnode, - ValueType type> : I_5_XZ_U<sop, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), op, - [(set GPR:$rz, (opnode GPR:$rx, type))]>; +class I_5_XZ_INS<bits<6> sop, dag outs, dag ins, string op, list<dag> pattern> + : CSKY32Inst<AddrModeNone, 0x31, outs, ins, op #"\t$rz, $rx, $msb, $lsb", + pattern> { + bits<5> rx; + bits<5> rz; + bits<5> msb; + bits<5> lsb; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = msb; + let Inst{4 - 0} = lsb; +} -class I_5_XZ_UZ<bits<6> sop, string op, int v> - : I_5_XZ_U<sop, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), op, - [(set GPR:$rz, (and GPR:$rx, (i32 v)))]>; +// Format< OP[6] | LSB[5] | RX[5] | SOP[6] | MSB[5] | RZ[5]> +// Instructions(6): zext32, zextb32, zexth32, sext32, sextb32, sexth32 +class I_5_XZ_U2<bits<6> sop, bits<5> lsb, bits<5> msb, dag outs, dag ins, + string op, list<dag> pattern> + : CSKY32Inst<AddrModeNone, 0x31, outs, ins, !strconcat(op, "\t$rz, $rx"), pattern> { + bits<5> rx; + bits<5> rz; + let Inst{25 - 21} = lsb; // lsb + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = msb; // msb + let Inst{4 - 0} = rz; +} // Format< OP[6] | RZ[5] | RX[5] | SOP[6] | SIZE[5] | LSB[5]> // Instructions(1): ins32 @@ -341,6 +456,16 @@ class I_5_ZX_U<bits<6> sop, string op, Operand operand, list<dag> pattern> let Inst{4 - 0} = size_lsb{4 - 0}; // lsb } +// sextb, sexth +class I_5_XZ_US<bits<6> sop, bits<5> lsb, bits<5> msb, string op, + SDNode opnode, ValueType type> + : I_5_XZ_U2<sop, lsb, msb, (outs GPR:$rz), (ins GPR:$rx), op, + [(set GPR:$rz, (opnode GPR:$rx, type))]>; + +class I_5_XZ_UZ<bits<6> sop, bits<5> lsb, bits<5> msb, string op, int v> + : I_5_XZ_U2<sop, lsb, msb, (outs GPR:$rz), (ins GPR:$rx), op, + [(set GPR:$rz, (and GPR:$rx, (i32 v)))]>; + // Format< OP[6] | IMM[5] | RX[5] | SOP[6] | PCODE[5] | 00000 > // Instructions(1): btsti32 class I_5_X<bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType, @@ -373,6 +498,18 @@ class I_5_Z<bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType, let Inst{4 - 0} = rz; } +class I_5_IMM5<bits<6> opcode, bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType, + list<dag> pattern> + : CSKY32Inst<AddrModeNone, opcode, (outs), (ins ImmType:$imm5), + !strconcat(op, "\t$imm5"), pattern> { + bits<5> imm5; + let Inst{25 - 21} = imm5; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; +} + // Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] > // Instructions(24): addu32, addc32, subu32, subc32, (rsub32), ixh32, ixw32, // ixd32, and32, andn32, or32, xor32, nor32, lsl32, lsr32, asr32, rotl32 @@ -493,9 +630,8 @@ class R_ZX<bits<6> sop, bits<5> pcode, string op, list<dag> pattern> // Format< OP[6] | 00000[5] | RX[5] | SOP[6] | PCODE[5] | 00000[5] > // Instructions:(1) tstnbz32 -class R_X<bits<6> sop, bits<5> pcode, string op, list<dag> pattern> - : CSKY32Inst<AddrModeNone, 0x31, (outs CARRY:$ca),(ins GPR:$rx), - !strconcat(op, "\t$rx"), pattern> { +class R_X<bits<6> sop, bits<5> pcode, dag outs, dag ins, string op, list<dag> pattern> + : CSKY32Inst<AddrModeNone, 0x31, outs, ins, !strconcat(op, "\t$rx"), pattern> { bits<5> rx; let Inst{25 - 21} = 0; let Inst{20 - 16} = rx; @@ -530,3 +666,14 @@ class R_Z_2<bits<6> sop, bits<5> pcode, string op, list<dag> pattern> let Inst{4 - 0} = 0; let Constraints = "$rz = $false"; } + +class BAR<bits<5> sop, string op, bits<1> signed> + : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), op, []> { + let Inst{25} = signed; + let Inst{24 - 16} = 0; + let Inst{15 - 5} = 0x421; + let Inst{4 - 0} = sop; + let hasSideEffects = 1; + let mayLoad = 0; + let mayStore = 0; +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats16Instr.td b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats16Instr.td new file mode 100644 index 000000000000..6d42bddcdd78 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats16Instr.td @@ -0,0 +1,219 @@ +//===- CSKYInstrFormats16Instr.td - 16-bit Instr. Formats -*- tablegen --*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +class J16<bits<5> sop, string opstr, dag ins> + : CSKY16Inst<AddrModeNone, (outs), ins, + !strconcat(opstr, "\t$offset"), []> { + bits<10> offset; + let Inst{15} = 0; + let Inst{14 - 10} = sop; + let Inst{9 - 0} = offset; +} + +class J16_B<bits<5> sop, string opstr> + : CSKY16Inst<AddrModeNone, (outs), (ins CARRY:$ca, br_symbol_16bit:$offset), + !strconcat(opstr, "\t$offset"), []> { + bits<10> offset; + let Inst{15} = 0; + let Inst{14 - 10} = sop; + let Inst{9 - 0} = offset; +} + +class R16_XYZ<bits<2> sop, string opstr, SDNode opnode> : CSKY16Inst<AddrModeNone, + (outs mGPR:$rz), (ins mGPR:$rx, mGPR:$ry), !strconcat(opstr, "\t$rz, $rx, $ry"), + [(set mGPR:$rz, (opnode mGPR:$rx, mGPR:$ry)) ]> { + bits<3> rz; + bits<3> rx; + bits<3> ry; + let Inst{15 - 11} = 0b01011; + let Inst{10 - 8} = rx; + let Inst{7 - 5} = rz; + let Inst{4 - 2} = ry; + let Inst{1, 0} = sop; +} + +class R16_XZ_BINOP<bits<4> op, bits<2> sop, string opstr, PatFrag opnode> : CSKY16Inst< + AddrModeNone, (outs sGPR:$rz), (ins sGPR:$rZ, sGPR:$rx), !strconcat(opstr, "\t$rz, $rx"), + [(set sGPR:$rz, (opnode sGPR:$rZ, sGPR:$rx))]> { + bits<4> rz; + bits<4> rx; + let Inst{15, 14} = 0b01; + let Inst{13 - 10} = op; + let Inst{9 - 6} = rz; + let Inst{5 - 2} = rx; + let Inst{1, 0} = sop; + let Constraints = "$rz = $rZ"; +} + +class R16_XZ_BINOP_NOPat<bits<4> op, bits<2> sop, string opstr> : CSKY16Inst< + AddrModeNone, (outs sGPR:$rz), (ins sGPR:$rZ, sGPR:$rx), !strconcat(opstr, "\t$rz, $rx"), + []> { + bits<4> rz; + bits<4> rx; + let Inst{15, 14} = 0b01; + let Inst{13 - 10} = op; + let Inst{9 - 6} = rz; + let Inst{5 - 2} = rx; + let Inst{1, 0} = sop; + let Constraints = "$rz = $rZ"; +} + +class R16_XZ_BINOP_C<bits<4> op, bits<2> sop, string opstr> : CSKY16Inst< + AddrModeNone, (outs sGPR:$rz, CARRY:$cout), + (ins sGPR:$rZ, sGPR:$rx, CARRY:$cin), !strconcat(opstr, "\t$rz, $rx"), []> { + bits<4> rz; + bits<4> rx; + let Inst{15, 14} = 0b01; + let Inst{13 - 10} = op; + let Inst{9 - 6} = rz; + let Inst{5 - 2} = rx; + let Inst{1, 0} = sop; + let Constraints = "$rz = $rZ"; +} + +class R16_XZ_UNOP<bits<4> op, bits<2> sop, string opstr> : CSKY16Inst< + AddrModeNone, (outs sGPR:$rz), (ins sGPR:$rx), !strconcat(opstr, "\t$rz, $rx"), + []> { + bits<4> rz; + bits<4> rx; + let Inst{15, 14} = 0b01; + let Inst{13 - 10} = op; + let Inst{9 - 6} = rz; + let Inst{5 - 2} = rx; + let Inst{1, 0} = sop; +} + +class R16_XY_CMP<bits<2> sop, string opstr> : CSKY16Inst< + AddrModeNone, (outs CARRY:$ca), (ins sGPR:$rx, sGPR:$ry), !strconcat(opstr, "\t$rx, $ry"), + []> { + bits<4> ry; + bits<4> rx; + let Inst{15, 14} = 0b01; + let Inst{13 - 10} = 0b1001; + let Inst{9 - 6} = ry; + let Inst{5 - 2} = rx; + let Inst{1, 0} = sop; + let isCompare = 1; +} + +class R16_X_J<bits<8> op_rz, bits<2> sop, string opstr> : CSKY16Inst< + AddrModeNone, (outs), (ins sGPR:$rx), !strconcat(opstr, "\t$rx"), []> { + bits<4> rx; + let Inst{15, 14} = 0b01; + let Inst{13 - 6} = op_rz; + let Inst{5 - 2} = rx; + let Inst{1, 0} = sop; +} + +class I16_Z_8<bits<3> op, dag ins, string asmstr> + : CSKY16Inst<AddrModeNone, (outs mGPR:$rz), ins, asmstr, []> { + bits<3> rz; + bits<8> imm8; + let Inst{15, 14} = 0b00; + let Inst{13 - 11} = op; + let Inst{10 - 8} = rz; + let Inst{7 - 0} = imm8; +} + +class I16_Z_5<bits<3> sop, dag outs, dag ins,string opstr> + : CSKY16Inst<AddrModeNone, outs, ins, + !strconcat(opstr, "\t$rz, $imm5"), []> { + bits<3> rz; + bits<5> imm5; + let Inst{15, 14} = 0b00; + let Inst{13 - 11} = 0b111; + let Inst{10 - 8} = rz; + let Inst{7 - 5} = sop; + let Inst{4 - 0} = imm5; +} + +class I16_X_CMP<bits<3> sop, string opstr, Operand Immoperand> : CSKY16Inst< + AddrModeNone, (outs CARRY:$ca), (ins mGPR:$rx, Immoperand:$imm5), + !strconcat(opstr, "\t$rx, $imm5"), []> { + bits<3> rx; + bits<5> imm5; + let Inst{15, 14} = 0b00; + let Inst{13 - 11} = 0b111; + let Inst{10 - 8} = rx; + let Inst{7 - 5} = sop; + let Inst{4 - 0} = imm5; + let isCompare = 1; +} + +class I16_SP_IMM7<bits<3> sop, string opstr> : CSKY16Inst< + AddrModeNone, (outs SPOp:$sp2), (ins SPOp:$sp1, uimm7_2:$imm7), + !strconcat(opstr, "\t$sp2, $sp1, $imm7"), []> { + bits<7> imm7; + let Inst{15, 14} = 0b00; + let Inst{13 - 10} = 0b0101; + let Inst{9, 8} = imm7{6,5}; + let Inst{7 - 5} = sop; + let Inst{4 - 0} = imm7{4 - 0}; +} + +class I16_XZ_IMM5<bits<3> sop, string opstr, SDNode opnode> : CSKY16Inst< + AddrModeNone, (outs mGPR:$rz), (ins mGPR:$rx, uimm5:$imm5), + !strconcat(opstr, "\t$rz, $rx, $imm5"), [(set mGPR:$rz, (opnode mGPR:$rx, uimm5:$imm5))]> { + bits<3> rx; + bits<3> rz; + bits<5> imm5; + let Inst{15, 14} = 0b01; + let Inst{13 - 11} = sop; + let Inst{10 - 8} = rx; + let Inst{7 - 5} = rz; + let Inst{4 - 0} = imm5; +} + +class I16_XZ_LDST<AddrMode am, bits<3> sop, string opstr, dag outs, dag ins> + : CSKY16Inst<am, outs, ins, !strconcat(opstr, "\t$rz, ($rx, ${imm})"), + []> { + bits<3> rx; + bits<3> rz; + bits<5> imm; + let Inst{15, 14} = 0b10; + let Inst{13 - 11} = sop; + let Inst{10 - 8} = rx; + let Inst{7 - 5} = rz; + let Inst{4 - 0} = imm; +} + +class I16_ZSP_LDST<AddrMode am, bits<3> sop, string opstr, dag outs, dag ins> : CSKY16Inst< + am, outs, ins, !strconcat(opstr, "\t$rz, ($sp, ${addr})"), + []> { + bits<3> rz; + bits<8> addr; + let Inst{15, 14} = 0b10; + let Inst{13 - 11} = sop; + let Inst{10 - 8} = addr{7 - 5}; + let Inst{7 - 5} = rz; + let Inst{4 - 0} = addr{4 - 0}; +} + +class I16_XZ_IMM3<bits<2> sop, string opstr, SDNode opnode> : CSKY16Inst< + AddrModeNone, (outs mGPR:$rz), (ins mGPR:$rx, oimm3:$oimm3), + !strconcat(opstr, "\t$rz, $rx, $oimm3"), [(set mGPR:$rz, (opnode mGPR:$rx, oimm3:$oimm3))]> { + bits<3> rx; + bits<3> rz; + bits<3> oimm3; + let Inst{15, 14} = 0b01; + let Inst{13 - 11} = 0b011; + let Inst{10 - 8} = rx; + let Inst{7 - 5} = rz; + let Inst{4 - 2} = oimm3; + let Inst{1, 0} = sop; +} + +class I16_BPushPop<bits<11> op, bits<2> uop, dag out, dag ins, string opstr> : + CSKY16Inst<AddrModeNone, out, ins, opstr, []>{ + bits<3> rz; + let Inst{15- 5} = op; + let Inst{4 -2} = rz; + let Inst{1,0} = uop; + let Predicates = [HasJAVA]; + let hasSideEffects = 1; +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp new file mode 100644 index 000000000000..e12235cf9478 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp @@ -0,0 +1,25 @@ +//===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYInstrInfo.h" +#include "llvm/MC/MCContext.h" + +#define DEBUG_TYPE "csky-instr-info" + +using namespace llvm; + +#define GET_INSTRINFO_CTOR_DTOR +#include "CSKYGenInstrInfo.inc" + +CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI) + : CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) { +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.h new file mode 100644 index 000000000000..04be9da27b57 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.h @@ -0,0 +1,36 @@ +//===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYINSTRINFO_H +#define LLVM_LIB_TARGET_CSKY_CSKYINSTRINFO_H + +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/CodeGen/TargetInstrInfo.h" + +#define GET_INSTRINFO_HEADER +#include "CSKYGenInstrInfo.inc" + +namespace llvm { + +class CSKYSubtarget; + +class CSKYInstrInfo : public CSKYGenInstrInfo { +protected: + const CSKYSubtarget &STI; + +public: + explicit CSKYInstrInfo(CSKYSubtarget &STI); +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYINSTRINFO_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td index 20adda4f9ca2..9dda3159e446 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td @@ -15,6 +15,18 @@ // CSKY specific DAG Nodes. //===----------------------------------------------------------------------===// +def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, + SDTCisVT<1, i32>]>; + +def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, + SDTCisVT<1, i32>]>; + +def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, + [SDNPHasChain, SDNPOutGlue]>; + +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; + // Target-dependent nodes. def CSKY_RET : SDNode<"CSKYISD::RET", SDTNone, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; @@ -44,6 +56,7 @@ class oimm<int num> : Operand<i32>, ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> { let EncoderMethod = "getOImmOpValue"; let ParserMatchClass = OImmAsmOperand<num>; + let DecoderMethod = "decodeOImmOperand<"#num#">"; } class uimm<int num, int shift = 0> : Operand<i32>, @@ -53,12 +66,14 @@ class uimm<int num, int shift = 0> : Operand<i32>, !if(!ne(shift, 0), UImmAsmOperand<num, "Shift"#shift>, UImmAsmOperand<num>); + let DecoderMethod = "decodeUImmOperand<"#num#", "#shift#">"; } class simm<int num, int shift = 0> : Operand<i32>, ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> { let EncoderMethod = "getImmOpValue<"#shift#">"; let ParserMatchClass = SImmAsmOperand<num>; + let DecoderMethod = "decodeSImmOperand<"#num#", "#shift#">"; } def nimm_XFORM : SDNodeXForm<imm, [{ @@ -73,14 +88,19 @@ def uimm32_hi16 : SDNodeXForm<imm, [{ return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF, SDLoc(N), MVT::i32); }]>; +def uimm32_lo16 : SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(N->getZExtValue()& 0xFFFF, SDLoc(N), MVT::i32); +}]>; def uimm16_16_xform : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> { let ParserMatchClass = UImmAsmOperand<16>; + let EncoderMethod = "getImmOpValue"; } def uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> { let EncoderMethod = "getImmShiftOpValue"; let ParserMatchClass = UImmAsmOperand<2>; + let DecoderMethod = "decodeImmShiftOpValue"; } def CSKYSymbol : AsmOperandClass { @@ -94,16 +114,22 @@ def br_symbol : Operand<iPTR> { let EncoderMethod = "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>"; let ParserMatchClass = CSKYSymbol; + let DecoderMethod = "decodeSImmOperand<16, 1>"; + let PrintMethod = "printCSKYSymbolOperand"; + let OperandType = "OPERAND_PCREL"; } def call_symbol : Operand<iPTR> { let ParserMatchClass = CSKYSymbol; let EncoderMethod = "getCallSymbolOpValue"; + let DecoderMethod = "decodeSImmOperand<26, 1>"; + let PrintMethod = "printCSKYSymbolOperand"; + let OperandType = "OPERAND_PCREL"; } def Constpool : AsmOperandClass { - let Name = "ConstpoolSymbol"; - let RenderMethod = "addImmOperands"; + let Name = "Constpool"; + let RenderMethod = "addConstpoolOperands"; let DiagnosticType = "InvalidConstpool"; let ParserMethod = "parseConstpoolSymbol"; } @@ -112,24 +138,132 @@ def constpool_symbol : Operand<iPTR> { let ParserMatchClass = Constpool; let EncoderMethod = "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>"; + let DecoderMethod = "decodeUImmOperand<16, 2>"; + let PrintMethod = "printConstpool"; + let OperandType = "OPERAND_PCREL"; +} + +def DataAsmClass : AsmOperandClass { + let Name = "DataSymbol"; + let RenderMethod = "addConstpoolOperands"; + let DiagnosticType = "InvalidConstpool"; + let ParserMethod = "parseDataSymbol"; +} + +class data_symbol<string reloc, int shift> : Operand<iPTR> { + let ParserMatchClass = Constpool; + let EncoderMethod = + "getDataSymbolOpValue<"#reloc#">"; + let DecoderMethod = "decodeUImmOperand<18, "#shift#">"; + let PrintMethod = "printDataSymbol"; } def bare_symbol : Operand<iPTR> { let ParserMatchClass = CSKYSymbol; let EncoderMethod = "getBareSymbolOpValue"; + let PrintMethod = "printCSKYSymbolOperand"; + let DecoderMethod = "decodeSImmOperand<18, 1>"; + let OperandType = "OPERAND_PCREL"; +} + +def oimm3 : oimm<3>; +def oimm4 : oimm<4>; +def oimm5 : oimm<5>; +def oimm6 : oimm<6>; + +def imm5_idly : Operand<i32>, ImmLeaf<i32, + "return Imm <= 32 && Imm >= 0;"> { + let EncoderMethod = "getImmOpValueIDLY"; + let DecoderMethod = "decodeOImmOperand<5>"; } +def oimm8 : oimm<8>; def oimm12 : oimm<12>; def oimm16 : oimm<16>; def nimm12 : nimm<12>; +def uimm1 : uimm<1>; +def uimm2 : uimm<2>; + + +def uimm2_jmpix : Operand<i32>, + ImmLeaf<i32, "return Imm == 16 || Imm == 24 || Imm == 32 || Imm == 40;"> { + let EncoderMethod = "getImmJMPIX"; + let DecoderMethod = "decodeJMPIXImmOperand"; +} + +def uimm3 : uimm<3>; +def uimm4 : uimm<4>; def uimm5 : uimm<5>; +def uimm5_msb_size : uimm<5> { + let EncoderMethod = "getImmOpValueMSBSize"; +} + +def uimm5_1 : uimm<5, 1>; +def uimm5_2 : uimm<5, 2>; +def uimm6 : uimm<6>; +def uimm7 : uimm<7>; +def uimm7_1 : uimm<7, 1>; +def uimm7_2 : uimm<7, 2>; +def uimm7_3 : uimm<7, 3>; +def uimm8 : uimm<8>; +def uimm8_2 : uimm<8, 2>; +def uimm8_3 : uimm<8, 3>; +def uimm8_8 : uimm<8, 8>; +def uimm8_16 : uimm<8, 16>; +def uimm8_24 : uimm<8, 24>; def uimm12 : uimm<12>; def uimm12_1 : uimm<12, 1>; def uimm12_2 : uimm<12, 2>; def uimm16 : uimm<16>; +def uimm16_8 : uimm<16, 8>; +def uimm16_16 : uimm<16, 16>; +def uimm20 : uimm<20>; +def uimm24 : uimm<24>; +def uimm24_8 : uimm<24, 8>; + +def simm8_2 : simm<8, 2>; + +class RegSeqAsmOperand<string Suffix = ""> : AsmOperandClass { + let Name = "RegSeq"#Suffix; + let RenderMethod = "addRegSeqOperands"; + let DiagnosticType = "InvalidRegSeq"; + let ParserMethod = "parseRegSeq"; +} + +def regseq : Operand<iPTR> { + let EncoderMethod = "getRegisterSeqOpValue"; + let ParserMatchClass = RegSeqAsmOperand<"">; + let PrintMethod = "printRegisterSeq"; + let DecoderMethod = "DecodeRegSeqOperand"; + let MIOperandInfo = (ops GPR, uimm5); +} +def RegListAsmOperand : AsmOperandClass { + let Name = "RegList"; + let RenderMethod = "addRegListOperands"; + let DiagnosticType = "InvalidRegList"; + let ParserMethod = "parseRegList"; +} + +def reglist : Operand<iPTR> { + let ParserMatchClass = RegListAsmOperand; + let PrintMethod = "printRegisterList"; +} + +def PSRFlag : AsmOperandClass { + let Name = "PSRFlag"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidPSRFlag"; + let ParserMethod = "parsePSRFlag"; +} + +def psrflag : Operand<i32>, ImmLeaf<i32, "return isShiftedUInt<5, 0>(Imm);"> { + let EncoderMethod = "getImmOpValue"; + let ParserMatchClass = PSRFlag; + let PrintMethod = "printPSRFlag"; +} //===----------------------------------------------------------------------===// // Instruction Formats @@ -145,12 +279,33 @@ class TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>; class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>; +def eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{ + return isOrEquivalentToAdd(N); +}]>; + +def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">; + + +//===----------------------------------------------------------------------===// +// CSKYPseudo +//===----------------------------------------------------------------------===// + +// Pessimistically assume the stack pointer will be clobbered +let Defs = [R14], Uses = [R14] in { +def ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), + "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>; +def ADJCALLSTACKUP : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), + "!ADJCALLSTACKUP $amt1, $amt2", [(callseq_end timm:$amt1, timm:$amt2)]>; +} // Defs = [R14], Uses = [R14] //===----------------------------------------------------------------------===// // Basic ALU instructions. //===----------------------------------------------------------------------===// +let Predicates = [iHasE2] in { + let isReMaterializable = 1, isAsCheapAsAMove = 1 in { + let isAdd = 1 in def ADDI32 : I_12<0x0, "addi32", add, oimm12>; def SUBI32 : I_12<0x1, "subi32", sub, oimm12>; def ORI32 : I_16_ZX<"ori32", uimm16, @@ -171,11 +326,15 @@ class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>; (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>; - + def ROTRI32 : CSKYPseudo<(outs GPR:$rz), (ins GPR:$rx, oimm5:$imm5), + "rotri32 $rz, $rx, $imm5", []>; + } + let isAdd = 1 in def ADDU32 : R_YXZ_SP_F1<0x0, 0x1, BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>; def SUBU32 : R_YXZ_SP_F1<0x0, 0x4, BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">; + def MULT32 : R_YXZ_SP_F1<0x21, 0x1, BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>; def AND32 : R_YXZ_SP_F1<0x8, 0x1, @@ -188,8 +347,16 @@ class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>; BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>; def NOR32 : R_YXZ_SP_F1<0x9, 0x4, BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>; + let isCodeGenOnly = 1 in def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx), "not32", [(set GPR:$rz, (not GPR:$rx))]>; + + let Size = 8 in + def NEG32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx), "neg32 $rd, $rx", []>; + + let Size = 8 in + def RSUBI32 : CSKYPseudo<(outs GPR:$rd), (ins GPR:$rx, uimm12:$imm12), "rsubi32 $rd, $rx, $imm12", []>; + def LSL32 : R_YXZ_SP_F1<0x10, 0x1, BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">; def LSR32 : R_YXZ_SP_F1<0x10, 0x2, @@ -199,23 +366,37 @@ class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>; def ROTL32 : R_YXZ_SP_F1<0x10, 0x8, BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">; - // TODO: Shift series instr. with carry. + def BMASKI32 : I_5_Z<0b010100, 0x1, "bmaski32", oimm5, []>; + def LSLC32 : I_5_XZ<0x13, 0x1, "lslc32", + (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>; + def LSRC32 : I_5_XZ<0x13, 0x2, "lsrc32", + (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>; + def ASRC32 : I_5_XZ<0x13, 0x4, "asrc32", + (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5), []>; + def XSR32 : I_5_XZ<0x13, 0x8, "xsr32", + (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, oimm5:$imm5, CARRY:$cin), []>; def IXH32 : R_YXZ_SP_F1<0x2, 0x1, BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">; def IXW32 : R_YXZ_SP_F1<0x2, 0x2, BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">; - + let Predicates = [iHas2E3] in def IXD32 : R_YXZ_SP_F1<0x2, 0x4, BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">; - let isCommutable = 1 in + let isCommutable = 1, isAdd = 1 in def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>; def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>; - // TODO: incf32. + def INCF32 : I_5_ZX<0x3, 0x1, "incf32", uimm5, []>; + def INCT32 : I_5_ZX<0x3, 0x2, "inct32", uimm5, []>; + def DECF32 : I_5_ZX<0x3, 0x4, "decf32", uimm5, []>; + def DECT32 : I_5_ZX<0x3, 0x8, "dect32", uimm5, []>; +} + +let Predicates = [iHas2E3] in { def DIVS32 : R_YXZ_SP_F1<0x20, 0x2, BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">; def DIVU32 : R_YXZ_SP_F1<0x20, 0x1, @@ -228,11 +409,35 @@ class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>; def DECNE32 : I_5_XZ<0x4, 0x4, "decne32", (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>; - // TODO: s/zext. - def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), - (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>; - def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), - (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>; + def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>; + let isCodeGenOnly = 1 in { + def SEXTB32 : I_5_XZ_US<0x16, 0, 7, "sextb32", sext_inreg, i8>; + def SEXTH32 : I_5_XZ_US<0x16, 0, 15, "sexth32", sext_inreg, i16>; + def ZEXTB32 : I_5_XZ_UZ<0x15, 0, 7, "zextb32", 255>; + def ZEXTH32 : I_5_XZ_UZ<0x15, 0, 15, "zexth32", 65535>; + } + def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz), (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>; + + let Constraints = "$rZ = $rz" in + def INS32 : I_5_XZ_INS<0b010111, (outs GPR:$rz), (ins GPR:$rZ, GPR:$rx, uimm5_msb_size:$msb, uimm5:$lsb), "ins32", []>; +} + +let Predicates = [iHas3E3r1] in { +def MULTS32 : R_YXZ<0x3e, 0x20, 0x10, (outs GPRPair:$rz), + (ins GPR:$rx, GPR:$ry), "mul.s32", []>; +def MULTU32 : R_YXZ<0x3e, 0x20, 0x00, (outs GPRPair:$rz), + (ins GPR:$rx, GPR:$ry), "mul.u32", []>; + +let Constraints = "$rZ = $rz" in { +def MULATS32 : R_YXZ<0x3e, 0x20, 0x14, (outs GPRPair:$rZ), + (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.s32", []>; +def MULATU32 : R_YXZ<0x3e, 0x20, 0x04, (outs GPRPair:$rZ), + (ins GPRPair:$rz, GPR:$rx, GPR:$ry), "mula.u32", []>; +} +} + +def MULSH32 : R_YXZ<0x31, 0b100100, 0b00001, (outs GPR:$rz), + (ins GPR:$rx, GPR:$ry), "mulsh32", []>; //===----------------------------------------------------------------------===// // Load & Store instructions. @@ -242,18 +447,35 @@ def LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>; def LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>; def LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>; +let OutOperandList = (outs GPRPair:$rz) in +def LD32D : I_LD<AddrMode32WD, 0x3, "ld32.d", uimm12_2>; +let Predicates = [iHasE2] in { def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>; def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>; - // TODO: LDM and STM. + def LDM32 : I_5_YX<0b110100, 0b000111, + (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "ldm32\t$regs, (${rx})", []>; + def STM32 : I_5_YX<0b110101, 0b000111, + (outs), (ins GPR:$rx, regseq:$regs, variable_ops), "stm32\t$regs, (${rx})", []>; + let Size = 4, isCodeGenOnly = 0 in { + def LDQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops), + "ldq32\t$regs, (${rx})", []>; + def STQ32 : CSKYPseudo<(outs), (ins GPR:$rx, regseq:$regs, variable_ops), + "stq32\t$regs, (${rx})", []>; + } + +} def ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>; def ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>; def ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>; +let InOperandList = (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm12 ) in +def ST32D : I_ST<AddrMode32WD, 0x3, "st32.d", uimm12_2>; +let Predicates = [iHas2E3] in { def LDR32B : I_LDR<0x0, "ldr32.b">; def LDR32BS : I_LDR<0x4, "ldr32.bs">; def LDR32H : I_LDR<0x1, "ldr32.h">; @@ -262,42 +484,100 @@ def ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>; def STR32B : I_STR<0x0, "str32.b">; def STR32H : I_STR<0x1, "str32.h">; def STR32W : I_STR<0x2, "str32.w">; +} + +// Indicate that we're dumping the CR register, so we'll need to +// scavenge a register for it. +let mayStore = 1 in { +def SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm), + "!SPILL_CARRY $cond, $rx, $imm", []>; +} + +// Indicate that we're restoring the CR register (previously +// spilled), so we'll need to scavenge a register for it. +let mayLoad = 1 in { +def RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm), + "!RESTORE_CARRY $cond, $rx, $imm", []>; +} - //TODO: SPILL_CARRY and RESTORE_CARRY. +let mayLoad = 1 in { +def STORE_PAIR : CSKYPseudo<(outs), (ins GPRPair:$rz, GPR:$rx, uimm12_2:$imm), + "!STORE_PAIR $rz, $rx, $imm", []>; +} + +let mayLoad = 1 in { +def LOAD_PAIR : CSKYPseudo<(outs GPRPair:$rz), (ins GPR:$rx, uimm12_2:$imm), + "!LOAD_PAIR $rz, $rx, $imm", []>; +} //===----------------------------------------------------------------------===// // Compare instructions. //===----------------------------------------------------------------------===// - +let Predicates = [iHasE2] in { def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>; def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>; def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>; - - + def CMPLEI32 : CSKYPseudo<(outs CARRY:$ca), (ins GPR:$rx, uimm16:$imm16), + "cmplei32\t$rx, $imm16", []>; +} +let Predicates = [iHas2E3] in { def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">; def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">; def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">; - // TODO: setc and clrc. - // TODO: test32 and tstnbz. + def SETC32 : CSKY32Inst<AddrModeNone, 0x31, + (outs CARRY:$ca), (ins), "setc32", []> { + let Inst{25 - 21} = 0; //rx + let Inst{20 - 16} = 0; //ry + let Inst{15 - 10} = 0x1; + let Inst{9 - 5} = 0x1; + let Inst{4 - 0} = 0; + let isCompare = 1; + } + def CLRC32 : CSKY32Inst<AddrModeNone, 0x31, + (outs CARRY:$ca), (ins), "clrc32", []> { + let Inst{25 - 21} = 0; //rx + let Inst{20 - 16} = 0; //ry + let Inst{15 - 10} = 0x1; + let Inst{9 - 5} = 0x4; + let Inst{4 - 0} = 0; + let isCompare = 1; + } + + def TST32 : R_YX<0x8, 0x4, "tst32">; + def TSTNBZ32 : R_X<0x8, 0x8, + (outs CARRY:$ca), (ins GPR:$rx), "tstnbz32", []>; +} //===----------------------------------------------------------------------===// // Data move instructions. //===----------------------------------------------------------------------===// +let Predicates= [iHasE2] in { + let isCodeGenOnly = 1 in { def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>; def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>; + } def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>; + let Size = 4, isCodeGenOnly = 0 in + def BGENI : CSKYPseudo<(outs GPR:$dst), (ins uimm5:$imm), "bgeni\t$dst, $imm", []>; + def : InstAlias<"bgeni16 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>; + def : InstAlias<"bgeni32 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>; def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>; def MVC32 : R_Z_1<0x1, 0x8, "mvc32">; + let isCodeGenOnly = 1 in def MOV32 : R_XZ<0x12, 0x1, "mov32">; - // TODO: ISEL Pseudo. + let usesCustomInserter = 1 in + def ISEL32 : CSKYPseudo<(outs GPR:$dst), (ins CARRY:$cond, GPR:$src1, GPR:$src2), + "!isel32\t$dst, $src1, src2", [(set GPR:$dst, (select CARRY:$cond, GPR:$src1, GPR:$src2))]>; +} +let Predicates = [iHas2E3] in { def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">; - // TODO: clrf and clrt. def CLRF32 : R_Z_2<0xB, 0x1, "clrf32", []>; def CLRT32 : R_Z_2<0xB, 0x2, "clrt32", []>; +} //===----------------------------------------------------------------------===// // Branch and call instructions. @@ -309,12 +589,12 @@ let isBranch = 1, isTerminator = 1 in { [(br bb:$imm16)]>; def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16), - "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>; + "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>, Requires<[iHasE2]>; def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16), - "bf32\t$imm16", []>; + "bf32\t$imm16", []>, Requires<[iHasE2]>; } - +let Predicates = [iHas2E3] in { def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>; def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>; def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>; @@ -334,10 +614,25 @@ let isBranch = 1, isTerminator = 1 in { let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in def JSRI32: I_16_L<0x17, (outs), (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>; +} +def BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a, + (outs GPR:$rx_u), (ins GPR:$rx, br_symbol:$imm16), "bnezad32\t$rx, $imm16", []> { + bits<5> rx; + bits<16> imm16; + let Inst{25 - 21} = 0x1; + let Inst{20 - 16} = rx; + let Inst{15 - 0} = imm16; + let isBranch = 1; + let isTerminator = 1; + let Constraints = "$rx_u = $rx"; + let Predicates = [iHas2E3, iHas10E60]; +} def BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>; +def : InstAlias<"bsr $dst", (BSR32 call_symbol:$dst)>; + def BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{ let isCodeGenOnly = 1; let isBranch = 1; @@ -347,27 +642,310 @@ def BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{ let Defs = [ R15 ]; } - +let Predicates = [iHasE2], isCodeGenOnly = 1 in { def RTS32 : I_16_RET<0x6, 0xF, "rts32", [(CSKY_RET)]>; +} -def RTE32 : I_16_RET_I<0, 0, "rte32", []>; - //===----------------------------------------------------------------------===// // Symbol address instructions. //===----------------------------------------------------------------------===// +def data_symbol_b : data_symbol<"CSKY::fixup_csky_doffset_imm18", 0>; +def data_symbol_h : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale2", 1>; +def data_symbol_w : data_symbol<"CSKY::fixup_csky_doffset_imm18_scale4", 2> { + let ParserMatchClass = DataAsmClass; +} + +let Predicates = [iHas2E3] in { + def GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset", (outs GPR:$rz), (ins bare_symbol:$offset), []>; +def : InstAlias<"grs\t$rz, $offset", (GRS32 GPR:$rz, bare_symbol:$offset)>; + +let Uses = [R28] in { +def LRS32B : I_18_Z_L<0x0, "lrs32.b\t$rz, $offset", + (outs GPR:$rz), (ins data_symbol_b:$offset), []>; +def LRS32H : I_18_Z_L<0x1, "lrs32.h\t$rz, $offset", + (outs GPR:$rz), (ins data_symbol_h:$offset), []>; +def LRS32W : I_18_Z_L<0x2, "lrs32.w\t$rz, $offset", + (outs GPR:$rz), (ins data_symbol_w:$offset), []>; +def SRS32B : I_18_Z_L<0x4, "srs32.b\t$rz, $offset", + (outs), (ins GPR:$rz, data_symbol_b:$offset), []>; +def SRS32H : I_18_Z_L<0x5, "srs32.h\t$rz, $offset", + (outs), (ins GPR:$rz, data_symbol_h:$offset), []>; +def SRS32W : I_18_Z_L<0x6, "srs32.w\t$rz, $offset", + (outs), (ins GPR:$rz, data_symbol_w:$offset), []>; +} + +def PUSH32 : I_12_PP<0b11111, 0b00000, (outs), (ins reglist:$regs, variable_ops), "push32 $regs">; + +let Uses = [R14, R15], isReturn = 1, isTerminator = 1, isBarrier = 1 in +def POP32 : I_12_PP<0b11110, 0b00000, (outs), (ins reglist:$regs, variable_ops), "pop32 $regs">; + +} let mayLoad = 1, mayStore = 0 in { def LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>; let isCodeGenOnly = 1 in -def LRW32_Gen : I_16_Z_L<0x14, "lrw32", - (ins bare_symbol:$src1, constpool_symbol:$imm16), []>; +def LRW32_Gen : I_16_Z_L<0x14, "lrw32", (ins bare_symbol:$src1, constpool_symbol:$imm16), []>; +} + +//===----------------------------------------------------------------------===// +// Atomic and fence instructions. +//===----------------------------------------------------------------------===// + +let Predicates = [iHasMP1E2] in { + def BRWARW : BAR<0b01111, "bar.brwarw", 0>; + def BRWARWS : BAR<0b01111, "bar.brwarws", 1>; + def BRARW : BAR<0b00111, "bar.brarw", 0>; + def BRARWS : BAR<0b00111, "bar.brarws", 1>; + def BRWAW : BAR<0b01110, "bar.brwaw", 0>; + def BRWAWS : BAR<0b01110, "bar.brwaws", 1>; + def BRAR : BAR<0b00101, "bar.brar", 0>; + def BRARS : BAR<0b00101, "bar.brars", 1>; + def BWAW : BAR<0b01010, "bar.bwaw", 0>; + def BWAWS : BAR<0b01010, "bar.bwaws", 1>; + + def LDEX32W : I_LD<AddrMode32WD, 0x7, "ldex32.w", uimm12_2>; + let Constraints = "$rd = $rz" in + def STEX32W : I_LDST<AddrMode32WD, 0x37, 7, + (outs GPR:$rd), (ins GPR:$rz, GPR:$rx, uimm12_2:$imm12), "stex32.w", []>; +} + +//===----------------------------------------------------------------------===// +// Other operation instructions. +//===----------------------------------------------------------------------===// + +let Predicates = [iHas2E3] in { + def BREV32 : R_XZ<0x18, 0x10, "brev32">; + def ABS32 : R_XZ<0x0, 0x10, "abs32">; + def BGENR32 : R_XZ<0x14, 0x2, "bgenr32">; +} + +let Predicates = [iHasE2] in { + def REVB32 : R_XZ<0x18, 0x4, "revb32">; + def REVH32 : R_XZ<0x18, 0x8, "revh32">; + def FF0 : R_XZ<0x1F, 0x1, "ff0.32">; + def FF1 : R_XZ<0x1F, 0x2, "ff1.32">; + def XTRB0 : R_XZ<0x1C, 0x1, "xtrb0.32">; + def XTRB1 : R_XZ<0x1C, 0x2, "xtrb1.32">; + def XTRB2 : R_XZ<0x1C, 0x4, "xtrb2.32">; + def XTRB3 : R_XZ<0x1C, 0x8, "xtrb3.32">; + def BTSTI32 : I_5_X<0x0A, 0x4, "btsti32", uimm5, []>; + def BCLRI32 : I_5_XZ<0xA, 0x1, "bclri32", + (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>; + def BSETI32 : I_5_XZ<0xA, 0x2, "bseti32", + (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), []>; +} + +//===----------------------------------------------------------------------===// +// Special instructions. +//===----------------------------------------------------------------------===// + +def MFFCR : CSKY32Inst<AddrModeNone, 0x30, + (outs GPR:$rx), (ins), "mfcr\t$rx, fcr", []> { + bits<5> rx; + + let Inst{25 - 21} = 0b00010; + let Inst{20 - 16} = 0b00001; + let Inst{15 - 10} = 0b011000; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = rx; + let hasSideEffects = 1; + let isCodeGenOnly = 1; +} + +def MTFCR : CSKY32Inst<AddrModeNone, 0x30, + (outs), (ins GPR:$rx), "mtcr\t$rx, fcr", []> { + bits<5> rx; + + let Inst{25 - 21} = 0b00010; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = 0b011001; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0b00001; + let hasSideEffects = 1; + let isCodeGenOnly = 1; +} + +def SYNC32 : I_5_IMM5<0x30, 0b000001, 0b00001, "sync32", uimm5, []>; + +def SYNC0_32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), + "sync32", []> { + let Inst{25 - 21} = 0; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = 0b000001; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0; +} + +def SYNC_32_I : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), + "sync32.i", []> { + let Inst{25 - 21} = 1; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = 0b000001; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0; +} + +def SYNC_32_S : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), + "sync32.s", []> { + let Inst{25 - 21} = 0b10000; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = 0b000001; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0; +} + +def SYNC_32_IS : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins), + "sync32.is", []> { + let Inst{25 - 21} = 0b10001; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = 0b000001; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0; } -// TODO: Atomic and fence instructions. -// TODO: Other operations. -// TODO: Special instructions. -// TODO: Pseudo for assembly. +let Predicates = [iHas2E3] in { + def RFI32 : I_5_XZ_PRIVI<0x11, 0x1, "rfi32">; + def SCE32 : I_5_IMM5<0x30, 0b000110, 0b00001, "sce32", uimm4, []>; +} +let Predicates = [HasExtendLrw] in +def IDLY32 : I_5_IMM5<0x30, 0b000111, 0b00001, "idly32", imm5_idly, []>; +def STOP32 : I_5_XZ_PRIVI<0x12, 0x1, "stop32">; +def WAIT32 : I_5_XZ_PRIVI<0x13, 0x1, "wait32">; +def DOZE32 : I_5_XZ_PRIVI<0x14, 0x1, "doze32">; +def WE32 : I_5_XZ_PRIVI<0b010101, 0x1, "we32">; +def SE32 : I_5_XZ_PRIVI<0b010110, 0x1, "se32">; +def WSC32 : I_5_XZ_PRIVI<0b001111, 0x1, "wsc32">; + +def CPOP32 : I_CPOP<(outs), (ins uimm5:$cpid, uimm20:$usdef), "cpop32 <$cpid, ${usdef}>">; +def CPRC32 : I_CP<0b0100, (outs CARRY:$ca), (ins uimm5:$cpid, uimm12:$usdef), "cprc32 <$cpid, ${usdef}>">; +def CPRCR32 : I_CP_Z<0b0010, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprcr32 $rz, <$cpid, ${usdef}>">; +def CPRGR32 : I_CP_Z<0b0000, (outs GPR:$rz), (ins uimm5:$cpid, uimm12:$usdef), "cprgr32 $rz, <$cpid, ${usdef}>">; +def CPWCR32 : I_CP_Z<0b0011, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwcr32 $rz, <$cpid, ${usdef}>">; +def CPWGR32 : I_CP_Z<0b0001, (outs), (ins GPR:$rz, uimm5:$cpid, uimm12:$usdef), "cpwgr32 $rz, <$cpid, ${usdef}>">; + +let Predicates = [iHas3r2E3r3] in { +def DCACHE_IALL32 : I_5_CACHE<0b100101, 0b01000, "dcache32.iall">; +def DCACHE_CALL32 : I_5_CACHE<0b100101, 0b00100, "dcache32.call">; +def DCACHE_CIALL32 : I_5_CACHE<0b100101, 0b01100, "dcache32.ciall">; +def DCACHE_IVA32 : I_5_X_CACHE<0b100101, 0b01011, "dcache32.iva">; +def DCACHE_ISW32: I_5_X_CACHE<0b100101, 0b01010, "dcache32.isw">; +def DCACHE_CVA32 : I_5_X_CACHE<0b100101, 0b00111, "dcache32.cva">; +def DCACHE_CVAL32 : I_5_X_CACHE<0b100101, 0b10111, "dcache32.cval1">; +def DCACHE_CSW32 : I_5_X_CACHE<0b100101, 0b00110, "dcache32.csw">; +def DCACHE_CIVA32 : I_5_X_CACHE<0b100101, 0b01111, "dcache32.civa">; +def DCACHE_CISW32 : I_5_X_CACHE<0b100101, 0b01110, "dcache32.cisw">; + +def ICACHE_IALL32 : I_5_CACHE<0b100100, 0b01000, "icache32.iall">; +def ICACHE_IALLS32 : I_5_CACHE<0b100100, 0b11000, "icache32.ialls">; +def ICACHE_IVA32 : I_5_X_CACHE<0b100100, 0b01011, "icache32.iva">; + +def TLBI_VAA32 : I_5_X_CACHE<0b100010, 0b00010, "tlbi32.vaa">; +def TLBI_VAAS32 : I_5_X_CACHE<0b100010, 0b10010, "tlbi32.vaas">; +def TLBI_ASID32 : I_5_X_CACHE<0b100010, 0b00001, "tlbi32.asid">; +def TLBI_ASIDS32 : I_5_X_CACHE<0b100010, 0b10001, "tlbi32.asids">; +def TLBI_VA32 : I_5_X_CACHE<0b100010, 0b00011, "tlbi32.va">; +def TLBI_VAS32 : I_5_X_CACHE<0b100010, 0b10011, "tlbi32.vas">; +def TLBI_ALL32 : I_5_CACHE<0b100010, 0b00000, "tlbi32.all">; +def TLBI_ALLS32 : I_5_CACHE<0b100010, 0b10000, "tlbi32.alls">; + +def L2CACHE_IALL : I_5_CACHE<0b100110, 0b01000, "l2cache.iall">; +def L2CACHE_CALL : I_5_CACHE<0b100110, 0b00100, "l2cache.call">; +def L2CACHE_CIALL : I_5_CACHE<0b100110, 0b01100, "l2cache.ciall">; +} + +def PLDR32 :I_PLDR<AddrMode32WD, 0x36, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldr32", []>; +def PLDW32 :I_PLDR<AddrMode32WD, 0x37, 0b0110, (outs), (ins GPR:$rx, uimm12_2:$imm12), "pldw32", []>; + +def TRAP32 : CSKY32Inst<AddrModeNone, 0x30, (outs), (ins uimm2:$imm2), "trap32 ${imm2}", []> { + bits<2> imm2; + + let Inst{25 - 21} = 0; + let Inst{20 - 16} = 0; + let Inst{15 - 12} = 0b0010; + let Inst{11 - 10} = imm2; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = 0; + +} + + +//===----------------------------------------------------------------------===// +// Pseudo for assembly +//===----------------------------------------------------------------------===// + +let isCall = 1, Defs = [ R15 ], mayLoad = 1, Size = 4, isCodeGenOnly = 0 in +def JBSR32 : CSKYPseudo<(outs), (ins call_symbol:$src1), "jbsr32\t$src1", []>; + +def : InstAlias<"jbsr\t$src1", (JBSR32 call_symbol:$src1)>; + +def JBR32 : CSKYPseudo<(outs), (ins br_symbol:$src1), "jbr32\t$src1", []> { + let isBranch = 1; + let isTerminator = 1; + let isBarrier = 1; + let isIndirectBranch = 1; + let mayLoad = 1; + let Size = 4; +} + +def JBT32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbt32\t$src1", []> { + let isBranch = 1; + let isTerminator = 1; + let isIndirectBranch = 1; + let mayLoad = 1; + let Size = 4; +} + +def JBF32 : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "jbf32\t$src1", []> { + let isBranch = 1; + let isTerminator = 1; + let isIndirectBranch = 1; + let mayLoad = 1; + let Size = 4; +} + +def JBT_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbt_e\t$src1", []> { + let isBranch = 1; + let isTerminator = 1; + let isIndirectBranch = 1; + let mayLoad = 1; + let Size = 6; +} + +def JBF_E : CSKYPseudo<(outs), (ins CARRY:$ca, br_symbol:$src1), "!jbf_e\t$src1", []> { + let isBranch = 1; + let isTerminator = 1; + let isIndirectBranch = 1; + let mayLoad = 1; + let Size = 6; +} + +let mayLoad = 1, Size = 2, isCodeGenOnly = 0 in +def PseudoLRW32 : CSKYPseudo<(outs GPR:$rz), (ins bare_symbol:$src), "lrw32 $rz, $src", []>; + + +def : InstAlias<"lrw $rz, $src", (PseudoLRW32 GPR:$rz, bare_symbol:$src)>; +def : InstAlias<"lrw $rz, $src", (LRW32 GPR:$rz, constpool_symbol:$src)>; + +let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in +def PseudoJSRI32 : CSKYPseudo<(outs), (ins call_symbol:$src), "jsri32 $src", []>; +def : InstAlias<"jsri $dst", (PseudoJSRI32 call_symbol:$dst)>; +def : InstAlias<"jsri $dst", (JSRI32 constpool_symbol:$dst)>; + +let mayLoad = 1, Size = 4, isCodeGenOnly = 0 in +def PseudoJMPI32 : CSKYPseudo<(outs), (ins br_symbol:$src), "jmpi32 $src", []>; +def : InstAlias<"jmpi $dst", (PseudoJMPI32 br_symbol:$dst)>; +def : InstAlias<"jmpi $dst", (JMPI32 constpool_symbol:$dst)>; + +let isNotDuplicable = 1, mayLoad = 1, mayStore = 0, Size = 8 in +def PseudoTLSLA32 : CSKYPseudo<(outs GPR:$dst1, GPR:$dst2), + (ins constpool_symbol:$src, i32imm:$label), "!tlslrw32\t$dst1, $dst2, $src, $label", []>; + +let hasSideEffects = 0, isNotDuplicable = 1 in +def CONSTPOOL_ENTRY : CSKYPseudo<(outs), + (ins i32imm:$instid, i32imm:$cpidx, i32imm:$size), "", []>; + +include "CSKYInstrInfo16Instr.td" diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo16Instr.td b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo16Instr.td new file mode 100644 index 000000000000..c98f43622155 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo16Instr.td @@ -0,0 +1,452 @@ +//===-- CSKYInstrInfo16Instr.td - CSKY 16-bit Instruction --*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the CSKY 16-bit instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// CSKY specific DAG Nodes. +//===----------------------------------------------------------------------===// + +// Target-dependent nodes. +def CSKY_NIE : SDNode<"CSKYISD::NIE", SDTNone, + [SDNPHasChain, SDNPOptInGlue]>; +def CSKY_NIR : SDNode<"CSKYISD::NIR", SDTNone, + [SDNPHasChain, SDNPOptInGlue]>; + +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +def br_symbol_16bit : Operand<iPTR> { + let EncoderMethod = + "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm10_scale2>"; + let ParserMatchClass = CSKYSymbol; + let DecoderMethod = "decodeSImmOperand<10, 1>"; + let PrintMethod = "printCSKYSymbolOperand"; + let OperandType = "OPERAND_PCREL"; +} + +def SPOperand : AsmOperandClass { + let Name = "SPOperand"; + let RenderMethod = "addRegOperands"; + let DiagnosticType = !strconcat("Invalid", Name); +} + +def SPOp : RegisterOperand<GPR> { + let ParserMatchClass = SPOperand; +} + +def constpool_symbol_16bit : Operand<iPTR> { + let ParserMatchClass = Constpool; + let EncoderMethod = + "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm7_scale4>"; + let DecoderMethod = "decodeLRW16Imm8"; + let PrintMethod = "printConstpool"; + let OperandType = "OPERAND_PCREL"; +} + +//===----------------------------------------------------------------------===// +// Instruction Formats +//===----------------------------------------------------------------------===// + +include "CSKYInstrFormats16Instr.td" + +//===----------------------------------------------------------------------===// +// Instruction definitions. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Basic ALU instructions. +//===----------------------------------------------------------------------===// + +let isCommutable = 1, isAdd = 1 in + def ADDU16 : R16_XYZ<0, "addu16", add>; +let Pattern = [(set mGPR:$rz, (sub mGPR:$rx, mGPR:$ry))] in + def SUBU16 : R16_XYZ<1, "subu16", sub>; + +let isCommutable = 1, isAdd = 1 in + def ADDC16 : R16_XZ_BINOP_C<0b1000, 0b01, "addc16">; +def SUBC16 : R16_XZ_BINOP_C<0b1000, 0b11, "subc16">; + +let isCommutable = 1 in { + let isAdd = 1 in + def ADDU16XZ : R16_XZ_BINOP<0b1000, 0b00, "addu16", BinOpFrag<(add node:$LHS, node:$RHS)>>; + def AND16 : R16_XZ_BINOP<0b1010, 0b00, "and16", BinOpFrag<(and node:$LHS, node:$RHS)>>; + def OR16 : R16_XZ_BINOP<0b1011, 0b00, "or16", BinOpFrag<(or node:$LHS, node:$RHS)>>; + def XOR16 : R16_XZ_BINOP<0b1011, 0b01, "xor16", BinOpFrag<(xor node:$LHS, node:$RHS)>>; + def NOR16 : R16_XZ_BINOP<0b1011, 0b10, "nor16", BinOpFrag<(not (or node:$LHS, node:$RHS))>>; + let isCodeGenOnly = 1 in + def NOT16 : R16_XZ_UNOP<0b1011, 0b10, "not16">; + def MULT16 : R16_XZ_BINOP<0b1111, 0b00, "mult16", BinOpFrag<(mul node:$LHS, node:$RHS)>>; +} +def SUBU16XZ : R16_XZ_BINOP<0b1000, 0b10, "subu16", BinOpFrag<(sub node:$LHS, node:$RHS)>>; +def ANDN16 : R16_XZ_BINOP<0b1010, 0b01, "andn16", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; +def LSL16 : R16_XZ_BINOP<0b1100, 0b00, "lsl16", BinOpFrag<(shl node:$LHS, node:$RHS)>>; +def LSR16 : R16_XZ_BINOP<0b1100, 0b01, "lsr16", BinOpFrag<(srl node:$LHS, node:$RHS)>>; +def ASR16 : R16_XZ_BINOP<0b1100, 0b10, "asr16", BinOpFrag<(sra node:$LHS, node:$RHS)>>; +def ROTL16 : R16_XZ_BINOP<0b1100, 0b11, "rotl16", BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>>; + +def MULSH16 : R16_XZ_BINOP_NOPat<0b1111, 0b01, "mulsh16">; + +def ZEXTB16 : R16_XZ_UNOP<0b1101, 0b00, "zextb16">; +def ZEXTH16 : R16_XZ_UNOP<0b1101, 0b01, "zexth16">; +def SEXTB16 : R16_XZ_UNOP<0b1101, 0b10, "sextb16">; +def SEXTH16 : R16_XZ_UNOP<0b1101, 0b11, "sexth16">; + +let Constraints = "$rZ = $rz", isReMaterializable = 1, isAsCheapAsAMove = 1 in { + let isAdd = 1, Pattern = [(set mGPR:$rz, (add mGPR:$rZ, oimm8:$imm8))] in + def ADDI16 : I16_Z_8<0b100, (ins mGPR:$rZ, oimm8:$imm8), "addi16\t$rz, $imm8">; + let Pattern = [(set mGPR:$rz, (sub mGPR:$rZ, oimm8:$imm8))] in + def SUBI16 : I16_Z_8<0b101, (ins mGPR:$rZ, oimm8:$imm8), "subi16\t$rz, $imm8">; +} + +let isAdd = 1 in +def ADDI16ZSP : I16_Z_8<0b011, (ins SPOp:$sp, uimm8_2:$imm8), + "addi16\t$rz, $sp, $imm8">; + +let isAdd = 1 in +def ADDI16SPSP : I16_SP_IMM7<0b000,"addi16">; +def SUBI16SPSP : I16_SP_IMM7<0b001,"subi16">; + +let isReMaterializable = 1, isAsCheapAsAMove = 1 in { + def LSLI16 : I16_XZ_IMM5<0, "lsli16", shl>; + def LSRI16 : I16_XZ_IMM5<1, "lsri16", srl>; + def ASRI16 : I16_XZ_IMM5<2, "asri16", sra>; +} + +let isAdd = 1 in +def ADDI16XZ : I16_XZ_IMM3<0b10, "addi16", add>; +def SUBI16XZ : I16_XZ_IMM3<0b11, "subi16", sub>; + +let Size = 4 in +def NEG16 : CSKYPseudo<(outs mGPR:$rd), (ins mGPR:$rx), "neg16 $rd, $rx", []>; + +let Size = 4 in +def RSUBI16 : CSKYPseudo<(outs mGPR:$rd), + (ins mGPR:$rx, uimm8:$imm8), "rsubi16 $rd, $rx, $imm8", []>; + +//===----------------------------------------------------------------------===// +// Load & Store instructions. +//===----------------------------------------------------------------------===// + +def LD16B : I16_XZ_LDST<AddrMode16B, 0b000, "ld16.b", + (outs mGPR:$rz), (ins mGPR:$rx, uimm5:$imm)>; +def LD16H : I16_XZ_LDST<AddrMode16H, 0b001, "ld16.h", + (outs mGPR:$rz), (ins mGPR:$rx, uimm5_1:$imm)>; +def LD16W : I16_XZ_LDST<AddrMode16W, 0b010, "ld16.w", + (outs mGPR:$rz), (ins mGPR:$rx, uimm5_2:$imm)>; +def ST16B : I16_XZ_LDST<AddrMode16B, 0b100, "st16.b", + (outs), (ins mGPR:$rz, mGPR:$rx, uimm5:$imm)>; +def ST16H : I16_XZ_LDST<AddrMode16H, 0b101, "st16.h", + (outs), (ins mGPR:$rz, mGPR:$rx, uimm5_1:$imm)>; +def ST16W : I16_XZ_LDST<AddrMode16W, 0b110, "st16.w", + (outs), (ins mGPR:$rz, mGPR:$rx, uimm5_2:$imm)>; + +def LD16WSP : I16_ZSP_LDST<AddrMode16W, 0b011, "ld16.w", + (outs mGPR:$rz), (ins SPOp:$sp, uimm8_2:$addr)>; +def ST16WSP : I16_ZSP_LDST<AddrMode16W, 0b111, "st16.w", + (outs), (ins mGPR:$rz, SPOp:$sp, uimm8_2:$addr)>; + +//===----------------------------------------------------------------------===// +// Compare instructions. +//===----------------------------------------------------------------------===// + +def CMPHS16 : R16_XY_CMP<0, "cmphs16">; +def CMPLT16 : R16_XY_CMP<1, "cmplt16">; +let isCommutable = 1 in +def CMPNE16 : R16_XY_CMP<2, "cmpne16">; + + +def CMPHSI16 : I16_X_CMP<0, "cmphsi16", oimm5>; +def CMPLTI16 : I16_X_CMP<1, "cmplti16", oimm5>; +def CMPLEI16 : CSKYPseudo<(outs CARRY:$ca), (ins mGPR:$rx, uimm5:$imm5), + "cmplei16\t$rx, $imm5", []>; +def CMPNEI16 : I16_X_CMP<2, "cmpnei16", uimm5>; + +//===----------------------------------------------------------------------===// +// Data move instructions. +//===----------------------------------------------------------------------===// + + +def MOVI16 : I16_Z_8<0b110, (ins uimm8:$imm8), "movi16\t$rz, $imm8"> { + let isReMaterializable = 1; + let isAsCheapAsAMove = 1; + let isMoveImm = 1; + let Pattern = [(set mGPR:$rz, uimm8:$imm8)]; +} + +def MOV16 : CSKY16Inst<AddrModeNone, (outs sGPR:$rz), (ins sGPR:$rx), + "mov16\t$rz, $rx", []> { + bits<4> rz; + bits<4> rx; + let Inst{15,14} = 0b01; + let Inst{13 - 10} = 0b1011; + let Inst{9 - 6} = rz; + let Inst{5 - 2} = rx; + let Inst{1,0} = 0b11; +} + +// MVC16 is not in "cskyv2 instructions reference manul" +def MVCV16 : CSKY16Inst<AddrModeNone, + (outs sGPR:$rz), (ins CARRY:$ca), "mvcv16\t$rz", []> { + bits<4> rz; + let Inst{15,14} = 0b01; + let Inst{13 - 10} = 0b1001; + let Inst{9 - 6} = rz; + let Inst{5 - 2} = 0; + let Inst{1,0} = 0b11; +} + + +//===----------------------------------------------------------------------===// +// Branch and call instructions. +//===----------------------------------------------------------------------===// + +let isBranch = 1, isTerminator = 1 in { + let isBarrier = 1, isPredicable = 1 in + def BR16 : J16<1, "br16", (ins br_symbol_16bit:$offset)>; + + def BT16 : J16_B<2, "bt16">; + def BF16 : J16_B<3, "bf16">; +} + +def JMP16 : R16_X_J<0b11100000, 0b00, "jmp16"> { + let isBranch = 1; + let isTerminator = 1; + let isBarrier = 1; + let isIndirectBranch = 1; + let Pattern = [(brind sGPR:$rx)]; +} + +def JSR16 : R16_X_J<0b11101111, 0b01, "jsr16"> { + let isCall = 1; + let Defs = [ R15 ]; +} + +def RTS16 : CSKY16Inst<AddrModeNone, (outs), (ins), "rts16", [(CSKY_RET)]> { + let isTerminator = 1; + let isReturn = 1; + let isBarrier = 1; + let Inst = 0b0111100000111100; + let Uses = [R15]; + let isCodeGenOnly = 1; +} + +def JMPIX16 : CSKY16Inst<AddrModeNone, (outs), + (ins mGPR:$rx, uimm2_jmpix:$indeximm2), "jmpix16\t$rx, $indeximm2", []> { + bits<3> rx; + bits<2> indeximm2; + let Inst{15,14} = 0b00; + let Inst{13 - 11} = 0b111; + let Inst{10 - 8} = rx; + let Inst{7 - 2} = 0b111000; + let Inst{1,0} = indeximm2; + let Predicates = [HasJAVA]; + let Uses = [R30]; +} + +//===----------------------------------------------------------------------===// +// Symbol address instructions. +//===----------------------------------------------------------------------===// + +def LRW16 : CSKY16Inst<AddrModeNone, (outs mGPR:$rz), + (ins constpool_symbol_16bit:$label), "lrw16\t$rz, $label", []> { + bits<3> rz; + bits<8> label; + let Inst{15 - 13} = 0b000; + let Inst{12} = label{7}; + let Inst{11,10} = 0b00; + let Inst{9,8} = label{6,5}; + let Inst{7 - 5} = rz; + let Inst{4 - 0} = label{4-0}; + let mayLoad = 1; + let mayStore = 0; +} + +def LRW16_Gen : CSKY16Inst<AddrModeNone, (outs mGPR:$rz), + (ins bare_symbol:$src, constpool_symbol_16bit:$label), + "lrw16\t$rz, $label", []> { + bits<3> rz; + bits<8> label; + let Inst{15 - 13} = 0b000; + let Inst{12} = label{7}; + let Inst{11,10} = 0b00; + let Inst{9,8} = label{6,5}; + let Inst{7 - 5} = rz; + let Inst{4 - 0} = label{4-0}; + let mayLoad = 1; + let mayStore = 0; + let isCodeGenOnly = 1; +} + + +//===----------------------------------------------------------------------===// +// Other operation instructions. +//===----------------------------------------------------------------------===// + +def REVB16 : R16_XZ_UNOP<0b1110, 0b10, "revb16">; +def REVH16 : R16_XZ_UNOP<0b1110, 0b11, "revh16">; + +let isCodeGenOnly = 1 in +def SETC16 : CSKY16Inst<AddrModeNone, + (outs CARRY:$ca), (ins), "setc16", []> { + let Inst{15, 14} = 0b01; + let Inst{13 - 10} = 0b1001; + let Inst{9 - 6} = 0; + let Inst{5 - 2} = 0; + let Inst{1, 0} = 0; + let isCompare = 1; +} + +let isCodeGenOnly = 1 in +def CLRC16 : CSKY16Inst<AddrModeNone, + (outs CARRY:$ca), (ins), "clrc16", []> { + let Inst{15, 14} = 0b01; + let Inst{13 - 10} = 0b1001; + let Inst{9 - 6} = 0; + let Inst{5 - 2} = 0; + let Inst{1, 0} = 2; + let isCompare = 1; +} + +let Constraints = "$rZ = $rz" in { + def BCLRI16 : I16_Z_5<0b100, (outs mGPR:$rz), (ins mGPR:$rZ, uimm5:$imm5), + "bclri16">; + def BSETI16 : I16_Z_5<0b101, (outs mGPR:$rz), (ins mGPR:$rZ, uimm5:$imm5), + "bseti16">; +} + +let Predicates = [HasBTST16] in + def BTSTI16 : I16_Z_5<0b110, (outs CARRY:$ca), (ins mGPR:$rz, uimm5:$imm5), + "btsti16">; + +def TST16 : CSKY16Inst<AddrModeNone, (outs CARRY:$ca), (ins sGPR:$rx, sGPR:$ry), + "tst16\t$rx, $ry", []> { + bits<4> ry; + bits<4> rx; + let Inst{15,14} = 0b01; + let Inst{13 - 10} = 0b1010; + let Inst{9 - 6} = ry; + let Inst{5 - 2} = rx; + let Inst{1,0} = 0b10; + let isCompare = 1; +} + +def TSTNBZ16 : CSKY16Inst<AddrModeNone, (outs CARRY:$ca), (ins sGPR:$rx), + "tstnbz16\t$rx", []> { + bits<4> rx; + let Inst{15,14} = 0b01; + let Inst{13 - 10} = 0b1010; + let Inst{9 - 6} = 0b0000; + let Inst{5 - 2} = rx; + let Inst{1,0} = 0b11; + let isCompare = 1; +} + +//===----------------------------------------------------------------------===// +// Special instructions. +//===----------------------------------------------------------------------===// + +def BKPT : CSKY16Inst<AddrModeNone, (outs), (ins), "bkpt", []> { + let Inst = 0; +} + +let mayStore = 1 in { +def BPUSHH : I16_BPushPop<0b00010100111, 0, (outs), (ins mGPR:$rz), "bpush.h $rz">; +def BPUSHW : I16_BPushPop<0b00010100111, 0b10, (outs), (ins mGPR:$rz), "bpush.w $rz">; +} + +let mayLoad = 1 in { +def BPOPH : I16_BPushPop<0b00010100101, 0, (outs mGPR:$rz), (ins), "bpop.h $rz">; +def BPOPW : I16_BPushPop<0b00010100101, 0b10, (outs mGPR:$rz), (ins), "bpop.w $rz">; +} + +def NIE : CSKY16Inst<AddrModeNone, (outs), (ins), "nie", [(CSKY_NIE)]> { + let Inst = 0b0001010001100000; +} + +let isBarrier = 1, isReturn = 1, isTerminator = 1 in +def NIR : CSKY16Inst<AddrModeNone, (outs), (ins), "nir", [(CSKY_NIR)]> { + let Inst = 0b0001010001100001; +} + +def IPUSH16 : CSKY16Inst<AddrModeNone, (outs), (ins), "ipush16", []> { + let Inst{15- 5} = 0b00010100011; + let Inst{4-0} = 0b00010; + let Predicates = [iHasE1]; + let Defs = [R14]; + let Uses = [R14, R0, R1, R2, R3, R12, R13]; + let mayStore = 1; +} + +def IPOP16 : CSKY16Inst<AddrModeNone, (outs), (ins), "ipop16", []> { + let Inst{15- 5} = 0b00010100011; + let Inst{4-0} = 0b00011; + let Predicates = [iHasE1]; + let Defs = [R14, R0, R1, R2, R3, R12, R13]; + let Uses = [R14]; + let mayLoad = 1; +} + +def PUSH16 : CSKY16Inst<AddrModeNone, (outs), + (ins reglist:$regs, variable_ops), "push16 $regs", []> { + bits<5> regs; + + let Inst{15- 5} = 0b00010100110; + let Inst{4-0} = regs; + let Predicates = [iHasE1]; + let Defs = [R14]; + let Uses = [R14]; + let mayStore = 1; +} + +def POP16 : CSKY16Inst<AddrModeNone, (outs), + (ins reglist:$regs, variable_ops), "pop16 $regs", []> { + bits<5> regs; + + let Inst{15- 5} = 0b00010100100; + let Inst{4-0} = regs; + let Predicates = [iHasE1]; + let Defs = [R14]; + let Uses = [R14]; + let mayLoad = 1; +} + +//===----------------------------------------------------------------------===// +// CSKYPseudo +//===----------------------------------------------------------------------===// + +let usesCustomInserter = 1 in { + def ISEL16 : CSKYPseudo<(outs sGPR:$dst), + (ins CARRY:$cond, sGPR:$src1, sGPR:$src2), + "!isel16\t$dst, $src1, src2", + [(set sGPR:$dst, (select CARRY:$cond, sGPR:$src1, sGPR:$src2))]>; +} + +class JBranchPseudo<dag out, dag ins, string opstr> : + CSKYPseudo<out, ins, opstr, []> { + let isBranch = 1; + let isTerminator = 1; + let isIndirectBranch = 1; + let mayLoad = 1; + let Size = 2; +} + +let isBarrier = 1 in +def JBR16 : JBranchPseudo<(outs), + (ins br_symbol_16bit:$src1), "jbr16\t$src1">; +def JBT16 : JBranchPseudo<(outs), + (ins CARRY:$ca, br_symbol_16bit:$src1), "jbt16\t$src1">; +def JBF16 : JBranchPseudo<(outs), + (ins CARRY:$ca, br_symbol_16bit:$src1), "jbf16\t$src1">; + +let mayLoad = 1, Size = 2, isCodeGenOnly = 0 in +def PseudoLRW16 : CSKYPseudo<(outs mGPR:$rz), + (ins bare_symbol:$src), "lrw16 $rz, $src", []>; diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.cpp new file mode 100644 index 000000000000..c42a56bfb04e --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.cpp @@ -0,0 +1,117 @@ +//===-- CSKYMCInstLower.cpp - Convert CSKY MachineInstr to an MCInst --------=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains code to lower CSKY MachineInstrs to their corresponding +// MCInst records. +// +//===----------------------------------------------------------------------===// + +#include "CSKYMCInstLower.h" +#include "MCTargetDesc/CSKYBaseInfo.h" +#include "MCTargetDesc/CSKYMCExpr.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/MC/MCExpr.h" + +#define DEBUG_TYPE "csky-mcinst-lower" + +using namespace llvm; + +CSKYMCInstLower::CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer) + : Ctx(Ctx), Printer(Printer) {} + +void CSKYMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { + OutMI.setOpcode(MI->getOpcode()); + + for (const MachineOperand &MO : MI->operands()) { + MCOperand MCOp; + if (lowerOperand(MO, MCOp)) + OutMI.addOperand(MCOp); + } +} + +MCOperand CSKYMCInstLower::lowerSymbolOperand(const MachineOperand &MO, + MCSymbol *Sym) const { + CSKYMCExpr::VariantKind Kind; + MCContext &Ctx = Printer.OutContext; + + switch (MO.getTargetFlags()) { + default: + llvm_unreachable("Unknown target flag."); + case CSKYII::MO_None: + Kind = CSKYMCExpr::VK_CSKY_None; + break; + case CSKYII::MO_GOT32: + Kind = CSKYMCExpr::VK_CSKY_GOT; + break; + case CSKYII::MO_GOTOFF: + Kind = CSKYMCExpr::VK_CSKY_GOTOFF; + break; + case CSKYII::MO_ADDR32: + Kind = CSKYMCExpr::VK_CSKY_ADDR; + break; + case CSKYII::MO_PLT32: + Kind = CSKYMCExpr::VK_CSKY_PLT; + break; + case CSKYII::MO_ADDR_HI16: + Kind = CSKYMCExpr::VK_CSKY_ADDR_HI16; + break; + case CSKYII::MO_ADDR_LO16: + Kind = CSKYMCExpr::VK_CSKY_ADDR_LO16; + break; + } + const MCExpr *ME = + MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); + + if (Kind != CSKYMCExpr::VK_CSKY_None) + ME = CSKYMCExpr::create(ME, Kind, Ctx); + + return MCOperand::createExpr(ME); +} + +bool CSKYMCInstLower::lowerOperand(const MachineOperand &MO, + MCOperand &MCOp) const { + switch (MO.getType()) { + default: + llvm_unreachable("unknown operand type"); + case MachineOperand::MO_RegisterMask: + break; + case MachineOperand::MO_Immediate: + MCOp = MCOperand::createImm(MO.getImm()); + break; + case MachineOperand::MO_Register: + if (MO.isImplicit()) + return false; + MCOp = MCOperand::createReg(MO.getReg()); + break; + case MachineOperand::MO_MachineBasicBlock: + MCOp = MCOperand::createExpr( + MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); + break; + case MachineOperand::MO_GlobalAddress: + MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); + break; + case MachineOperand::MO_BlockAddress: + MCOp = lowerSymbolOperand( + MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); + break; + case MachineOperand::MO_ExternalSymbol: + MCOp = lowerSymbolOperand( + MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); + break; + case MachineOperand::MO_ConstantPoolIndex: + MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); + break; + case MachineOperand::MO_JumpTableIndex: + MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); + break; + case MachineOperand::MO_MCSymbol: + MCOp = lowerSymbolOperand(MO, MO.getMCSymbol()); + break; + } + return true; +}
\ No newline at end of file diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.h new file mode 100644 index 000000000000..ea76bd129d30 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.h @@ -0,0 +1,35 @@ +//===-- CSKYMCInstLower.cpp - Convert CSKY MachineInstr to an MCInst --------=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYMCINSTLOWER_H +#define LLVM_LIB_TARGET_CSKY_CSKYMCINSTLOWER_H + +namespace llvm { +class AsmPrinter; +class MCContext; +class MachineInstr; +class MCInst; +class MachineOperand; +class MCOperand; +class MCSymbol; + +class CSKYMCInstLower { + MCContext &Ctx; + AsmPrinter &Printer; + +public: + CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer); + + void Lower(const MachineInstr *MI, MCInst &OutMI) const; + bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const; + MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYMCINSTLOWER_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h new file mode 100644 index 000000000000..b6e303f8ccfb --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h @@ -0,0 +1,62 @@ +//=- CSKYMachineFunctionInfo.h - CSKY machine function info -------*- C++ -*-=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares CSKY-specific per-machine-function information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYMACHINEFUNCTIONINFO_H +#define LLVM_LIB_TARGET_CSKY_CSKYMACHINEFUNCTIONINFO_H + +#include "llvm/CodeGen/MachineFunction.h" + +namespace llvm { + +class CSKYMachineFunctionInfo : public MachineFunctionInfo { + MachineFunction &MF; + + Register GlobalBaseReg = 0; + bool SpillsCR = false; + + int VarArgsFrameIndex = 0; + unsigned VarArgsSaveSize = 0; + + int spillAreaSize = 0; + + bool LRSpilled = false; + + unsigned PICLabelUId = 0; + +public: + CSKYMachineFunctionInfo(MachineFunction &MF) : MF(MF) {} + + Register getGlobalBaseReg() const { return GlobalBaseReg; } + void setGlobalBaseReg(Register Reg) { GlobalBaseReg = Reg; } + + void setSpillsCR() { SpillsCR = true; } + bool isCRSpilled() const { return SpillsCR; } + + void setVarArgsFrameIndex(int v) { VarArgsFrameIndex = v; } + int getVarArgsFrameIndex() { return VarArgsFrameIndex; } + + unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; } + void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; } + + bool isLRSpilled() const { return LRSpilled; } + void setLRIsSpilled(bool s) { LRSpilled = s; } + + void setCalleeSaveAreaSize(int v) { spillAreaSize = v; } + int getCalleeSaveAreaSize() const { return spillAreaSize; } + + unsigned createPICLabelUId() { return ++PICLabelUId; } + void initPICLabelUId(unsigned UId) { PICLabelUId = UId; } +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYMACHINEFUNCTIONINFO_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp new file mode 100644 index 000000000000..a1d45fea534b --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp @@ -0,0 +1,95 @@ +//===-- CSKYRegisterInfo.h - CSKY Register Information Impl ---*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYRegisterInfo.h" +#include "CSKY.h" +#include "CSKYSubtarget.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/MC/MCContext.h" + +#define GET_REGINFO_TARGET_DESC +#include "CSKYGenRegisterInfo.inc" + +using namespace llvm; + +CSKYRegisterInfo::CSKYRegisterInfo() + : CSKYGenRegisterInfo(CSKY::R15, 0, 0, 0) {} + +const uint32_t * +CSKYRegisterInfo::getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID Id) const { + const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>(); + return CSR_I32_RegMask; +} + +Register CSKYRegisterInfo::getFrameRegister(const MachineFunction &MF) const { + const TargetFrameLowering *TFI = getFrameLowering(MF); + return TFI->hasFP(MF) ? CSKY::R8 : CSKY::R14; +} + +BitVector CSKYRegisterInfo::getReservedRegs(const MachineFunction &MF) const { + const CSKYFrameLowering *TFI = getFrameLowering(MF); + const CSKYSubtarget &STI = MF.getSubtarget<CSKYSubtarget>(); + BitVector Reserved(getNumRegs()); + + // Reserve the base register if we need to allocate + // variable-sized objects at runtime. + if (TFI->hasBP(MF)) + markSuperRegs(Reserved, CSKY::R7); // bp + + if (TFI->hasFP(MF)) + markSuperRegs(Reserved, CSKY::R8); // fp + + if (!STI.hasE2()) { + for (unsigned i = 0; i < 6; i++) + markSuperRegs(Reserved, CSKY::R8 + i); // R8 - R13 + } + + markSuperRegs(Reserved, CSKY::R14); // sp + markSuperRegs(Reserved, CSKY::R15); // lr + + if (!STI.hasHighRegisters()) { + for (unsigned i = 0; i < 10; i++) + markSuperRegs(Reserved, CSKY::R16 + i); // R16 - R25 + } + + markSuperRegs(Reserved, CSKY::R26); + markSuperRegs(Reserved, CSKY::R27); + markSuperRegs(Reserved, CSKY::R28); // gp + markSuperRegs(Reserved, CSKY::R29); + markSuperRegs(Reserved, CSKY::R30); + markSuperRegs(Reserved, CSKY::R31); // tp + + assert(checkAllSuperRegsMarked(Reserved)); + return Reserved; +} + +const uint32_t *CSKYRegisterInfo::getNoPreservedMask() const { + return CSR_NoRegs_RegMask; +} + +const MCPhysReg * +CSKYRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + const CSKYSubtarget &STI = MF->getSubtarget<CSKYSubtarget>(); + if (MF->getFunction().hasFnAttribute("interrupt")) { + return CSR_GPR_ISR_SaveList; + } + + return CSR_I32_SaveList; +} + +void CSKYRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, unsigned FIOperandNum, + RegScavenger *RS) const { + assert(SPAdj == 0 && "Unexpected non-zero SPAdj value"); +}
\ No newline at end of file diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.h new file mode 100644 index 000000000000..779ea6493c7e --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.h @@ -0,0 +1,45 @@ +//===-- CSKYRegisterInfo.h - CSKY Register Information Impl ---*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYREGISTERINFO_H +#define LLVM_LIB_TARGET_CSKY_CSKYREGISTERINFO_H + +#include "llvm/CodeGen/TargetRegisterInfo.h" + +#define GET_REGINFO_HEADER +#include "CSKYGenRegisterInfo.inc" + +namespace llvm { +class CSKYInstrInfo; + +class CSKYRegisterInfo : public CSKYGenRegisterInfo { +public: + CSKYRegisterInfo(); + + const uint32_t *getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID id) const override; + const uint32_t *getNoPreservedMask() const override; + + BitVector getReservedRegs(const MachineFunction &MF) const override; + + Register getFrameRegister(const MachineFunction &MF) const override; + + const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; + + void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, + unsigned FIOperandNum, + RegScavenger *RS) const override; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYREGISTERINFO_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.td b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.td index aef4589a67f2..7548c22bb2c5 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.td +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.td @@ -153,6 +153,21 @@ def GPR : RegisterClass<"CSKY", [i32], 32, let Size = 32; } +// Register class for R0 - R15. +// Some 16-bit integer instructions can only access R0 - R15. +def sGPR : RegisterClass<"CSKY", [i32], 32, + (add (sequence "R%u", 0, 3), (sequence "R%u", 12, 13), R15, + (sequence "R%u", 4, 11), R14)> { + let Size = 32; +} + +// Register class for R0 - R7. +// Some 16-bit integer instructions can only access R0 - R7. +def mGPR : RegisterClass<"CSKY", [i32], 32, + (add (sequence "R%u", 0, 7))> { + let Size = 32; +} + def GPRPair : RegisterClass<"CSKY", [untyped], 32, (add GPRTuple)> { let Size = 64; } diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.cpp new file mode 100644 index 000000000000..963c2ede9c44 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.cpp @@ -0,0 +1,74 @@ +//===-- CSKYSubtarget.h - Define Subtarget for the CSKY----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the CSKY specific subclass of TargetSubtargetInfo. +// +//===----------------------------------------------------------------------===// + +#include "CSKYSubtarget.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-subtarget" +#define GET_SUBTARGETINFO_TARGET_DESC +#define GET_SUBTARGETINFO_CTOR +#include "CSKYGenSubtargetInfo.inc" + +void CSKYSubtarget::anchor() {} + +CSKYSubtarget &CSKYSubtarget::initializeSubtargetDependencies( + const Triple &TT, StringRef CPUName, StringRef TuneCPUName, StringRef FS) { + + if (CPUName.empty()) + CPUName = "generic"; + if (TuneCPUName.empty()) + TuneCPUName = CPUName; + + UseHardFloat = false; + UseHardFloatABI = false; + HasFPUv2SingleFloat = false; + HasFPUv2DoubleFloat = false; + HasFPUv3SingleFloat = false; + HasFPUv3DoubleFloat = false; + + HasBTST16 = false; + HasJAVA = false; + HasExtendLrw = false; + HasDoloop = false; + HasHighRegisters = false; + + HasE1 = false; + HasE2 = false; + Has2E3 = false; + HasMP = false; + Has3E3r1 = false; + Has3r1E3r2 = false; + Has3r2E3r3 = false; + Has3E7 = false; + HasMP1E2 = false; + Has7E10 = false; + Has10E60 = false; + + ParseSubtargetFeatures(CPUName, TuneCPUName, FS); + return *this; +} + +CSKYSubtarget::CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, + StringRef FS, const TargetMachine &TM) + : CSKYGenSubtargetInfo(TT, CPU, TuneCPU, FS), + FrameLowering(initializeSubtargetDependencies(TT, CPU, TuneCPU, FS)), + InstrInfo(*this), RegInfo(), TLInfo(TM, *this) {} + +bool CSKYSubtarget::useHardFloatABI() const { + auto FloatABI = getTargetLowering()->getTargetMachine().Options.FloatABIType; + + if (FloatABI == FloatABI::Default) + return UseHardFloatABI; + else + return FloatABI == FloatABI::Hard; +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.h new file mode 100644 index 000000000000..4cd590e8e76e --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.h @@ -0,0 +1,120 @@ +//===-- CSKYSubtarget.h - Define Subtarget for the CSKY----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the CSKY specific subclass of TargetSubtargetInfo. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYSUBTARGET_H +#define LLVM_LIB_TARGET_CSKY_CSKYSUBTARGET_H + +#include "CSKYFrameLowering.h" +#include "CSKYISelLowering.h" +#include "CSKYInstrInfo.h" +#include "CSKYRegisterInfo.h" +#include "llvm/CodeGen/SelectionDAGTargetInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/Target/TargetMachine.h" + +#define GET_SUBTARGETINFO_HEADER +#include "CSKYGenSubtargetInfo.inc" + +namespace llvm { +class StringRef; + +class CSKYSubtarget : public CSKYGenSubtargetInfo { + virtual void anchor(); + + CSKYFrameLowering FrameLowering; + CSKYInstrInfo InstrInfo; + CSKYRegisterInfo RegInfo; + CSKYTargetLowering TLInfo; + SelectionDAGTargetInfo TSInfo; + + bool UseHardFloat; + bool UseHardFloatABI; + bool HasFPUv2SingleFloat; + bool HasFPUv2DoubleFloat; + bool HasFPUv3SingleFloat; + bool HasFPUv3DoubleFloat; + + bool HasBTST16; + bool HasJAVA; + bool HasExtendLrw; + bool HasDoloop; + bool HasHighRegisters; + + bool HasE1; + bool HasE2; + bool Has2E3; + bool HasMP; + bool Has3E3r1; + bool Has3r1E3r2; + bool Has3r2E3r3; + bool Has3E7; + bool HasMP1E2; + bool Has7E10; + bool Has10E60; + +public: + CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, + StringRef FS, const TargetMachine &TM); + + const CSKYFrameLowering *getFrameLowering() const override { + return &FrameLowering; + } + const CSKYInstrInfo *getInstrInfo() const override { return &InstrInfo; } + const CSKYRegisterInfo *getRegisterInfo() const override { return &RegInfo; } + const CSKYTargetLowering *getTargetLowering() const override { + return &TLInfo; + } + const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { + return &TSInfo; + } + + /// Initializes using the passed in CPU and feature strings so that we can + /// use initializer lists for subtarget initialization. + CSKYSubtarget &initializeSubtargetDependencies(const Triple &TT, + StringRef CPU, + StringRef TuneCPU, + StringRef FS); + + // Generated by inc file + void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); + + bool useHardFloatABI() const; + bool useHardFloat() const { return UseHardFloat; } + bool hasFPUv2SingleFloat() const { return HasFPUv2SingleFloat; } + bool hasFPUv2DoubleFloat() const { return HasFPUv2DoubleFloat; } + bool hasFPUv2() const { return HasFPUv2SingleFloat || HasFPUv2DoubleFloat; } + bool hasFPUv3SingleFloat() const { return HasFPUv3SingleFloat; } + bool hasFPUv3DoubleFloat() const { return HasFPUv3DoubleFloat; } + bool hasFPUv3() const { return HasFPUv3SingleFloat || HasFPUv3DoubleFloat; } + bool hasAnyFloatExt() const { return hasFPUv2() || hasFPUv3(); }; + + bool hasBTST16() const { return HasBTST16; } + bool hasJAVA() const { return HasJAVA; } + bool hasExtendLrw() const { return HasExtendLrw; } + bool hasDoloop() const { return HasDoloop; } + bool hasHighRegisters() const { return HasHighRegisters; } + + bool hasE1() const { return HasE1; } + bool hasE2() const { return HasE2; } + bool has2E3() const { return Has2E3; } + bool has3r1E3r2() const { return Has3r1E3r2; } + bool has3r2E3r3() const { return Has3r2E3r3; } + bool has3E3r1() const { return Has3E3r1; } + bool has3E7() const { return Has3E7; } + bool hasMP() const { return HasMP; } + bool hasMP1E2() const { return HasMP1E2; } + bool has7E10() const { return Has7E10; } + bool has10E60() const { return Has10E60; } +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYSUBTARGET_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp index 1c13796e84b6..8f61feb6506d 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp @@ -11,10 +11,13 @@ //===----------------------------------------------------------------------===// #include "CSKYTargetMachine.h" +#include "CSKY.h" +#include "CSKYSubtarget.h" #include "TargetInfo/CSKYTargetInfo.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/CodeGen/TargetPassConfig.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/MC/TargetRegistry.h" using namespace llvm; @@ -50,6 +53,34 @@ CSKYTargetMachine::CSKYTargetMachine(const Target &T, const Triple &TT, initAsmInfo(); } +const CSKYSubtarget * +CSKYTargetMachine::getSubtargetImpl(const Function &F) const { + Attribute CPUAttr = F.getFnAttribute("target-cpu"); + Attribute TuneAttr = F.getFnAttribute("tune-cpu"); + Attribute FSAttr = F.getFnAttribute("target-features"); + + std::string CPU = + CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; + std::string TuneCPU = + TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; + std::string FS = + FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; + + std::string Key = CPU + TuneCPU + FS; + auto &I = SubtargetMap[Key]; + if (!I) { + // This needs to be done before we create a new subtarget since any + // creation will depend on the TM and the code generation flags on the + // function that reside in TargetOptions. + resetTargetOptions(F); + I = std::make_unique<CSKYSubtarget>(TargetTriple, CPU, TuneCPU, FS, *this); + if (I->useHardFloat() && !I->hasAnyFloatExt()) + errs() << "Hard-float can't be used with current CPU," + " set to Soft-float\n"; + } + return I.get(); +} + namespace { class CSKYPassConfig : public TargetPassConfig { public: @@ -59,6 +90,8 @@ public: CSKYTargetMachine &getCSKYTargetMachine() const { return getTM<CSKYTargetMachine>(); } + + bool addInstSelector() override; }; } // namespace @@ -66,3 +99,9 @@ public: TargetPassConfig *CSKYTargetMachine::createPassConfig(PassManagerBase &PM) { return new CSKYPassConfig(*this, PM); } + +bool CSKYPassConfig::addInstSelector() { + addPass(createCSKYISelDag(getCSKYTargetMachine())); + + return false; +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.h b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.h index d50e3877b550..ecb9fe953077 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.h +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.h @@ -13,6 +13,7 @@ #ifndef LLVM_LIB_TARGET_CSKY_CSKYTARGETMACHINE_H #define LLVM_LIB_TARGET_CSKY_CSKYTARGETMACHINE_H +#include "CSKYSubtarget.h" #include "llvm/IR/DataLayout.h" #include "llvm/Target/TargetMachine.h" @@ -20,6 +21,7 @@ namespace llvm { class CSKYTargetMachine : public LLVMTargetMachine { std::unique_ptr<TargetLoweringObjectFile> TLOF; + mutable StringMap<std::unique_ptr<CSKYSubtarget>> SubtargetMap; public: CSKYTargetMachine(const Target &T, const Triple &TT, StringRef CPU, @@ -29,6 +31,12 @@ public: TargetPassConfig *createPassConfig(PassManagerBase &PM) override; + const CSKYSubtarget *getSubtargetImpl(const Function &F) const override; + // DO NOT IMPLEMENT: There is no such thing as a valid default subtarget, + // subtargets are per-function entities based on the target-specific + // attributes of each function. + const CSKYSubtarget *getSubtargetImpl() const = delete; + TargetLoweringObjectFile *getObjFileLowering() const override { return TLOF.get(); } diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp index 7fb5f35548b4..daa655416c47 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp @@ -30,25 +30,57 @@ CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { static llvm::DenseMap<unsigned, MCFixupKindInfo> Infos = { {CSKY::Fixups::fixup_csky_addr32, {"fixup_csky_addr32", 0, 32, 0}}, + {CSKY::Fixups::fixup_csky_addr_hi16, {"fixup_csky_addr_hi16", 0, 32, 0}}, + {CSKY::Fixups::fixup_csky_addr_lo16, {"fixup_csky_addr_lo16", 0, 32, 0}}, {CSKY::Fixups::fixup_csky_pcrel_imm16_scale2, {"fixup_csky_pcrel_imm16_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, {CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4, - {"fixup_csky_pcrel_uimm16_scale4", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, + {"fixup_csky_pcrel_uimm16_scale4", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}}, + {CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4, + {"fixup_csky_pcrel_uimm8_scale4", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}}, {CSKY::Fixups::fixup_csky_pcrel_imm26_scale2, {"fixup_csky_pcrel_imm26_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, {CSKY::Fixups::fixup_csky_pcrel_imm18_scale2, - {"fixup_csky_pcrel_imm18_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}}; + {"fixup_csky_pcrel_imm18_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_got32, {"fixup_csky_got32", 0, 32, 0}}, + {CSKY::Fixups::fixup_csky_got_imm18_scale4, + {"fixup_csky_got_imm18_scale4", 0, 32, 0}}, + {CSKY::Fixups::fixup_csky_gotoff, {"fixup_csky_gotoff", 0, 32, 0}}, + {CSKY::Fixups::fixup_csky_gotpc, + {"fixup_csky_gotpc", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_plt32, {"fixup_csky_plt32", 0, 32, 0}}, + {CSKY::Fixups::fixup_csky_plt_imm18_scale4, + {"fixup_csky_plt_imm18_scale4", 0, 32, 0}}, + {CSKY::Fixups::fixup_csky_pcrel_imm10_scale2, + {"fixup_csky_pcrel_imm10_scale2", 0, 16, MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4, + {"fixup_csky_pcrel_uimm7_scale4", 0, 16, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}}, + {CSKY::Fixups::fixup_csky_doffset_imm18, + {"fixup_csky_doffset_imm18", 0, 18, 0}}, + {CSKY::Fixups::fixup_csky_doffset_imm18_scale2, + {"fixup_csky_doffset_imm18_scale2", 0, 18, 0}}, + {CSKY::Fixups::fixup_csky_doffset_imm18_scale4, + {"fixup_csky_doffset_imm18_scale4", 0, 18, 0}}}; + assert(Infos.size() == CSKY::NumTargetFixupKinds && "Not all fixup kinds added to Infos array"); - assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && - "Invalid kind!"); - if (FirstTargetFixupKind <= Kind && Kind < FirstLiteralRelocationKind) + if (FirstTargetFixupKind <= Kind && Kind < FirstLiteralRelocationKind) { + assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && + "Invalid kind!"); + return Infos[Kind]; - else if (Kind < FirstTargetFixupKind) + } else if (Kind < FirstTargetFixupKind) { return MCAsmBackend::getFixupKindInfo(Kind); - else + } else { return MCAsmBackend::getFixupKindInfo(FK_NONE); + } } static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, @@ -145,7 +177,8 @@ void CSKYAsmBackend::relaxInstruction(MCInst &Inst, llvm_unreachable("CSKYAsmBackend::relaxInstruction() unimplemented"); } -bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { if (Count % 2) return false; diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h index cdf688e9032a..e710954e9df8 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h @@ -39,7 +39,8 @@ public: void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; std::unique_ptr<MCObjectTargetWriter> createObjectTargetWriter() const override; diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYBaseInfo.h b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYBaseInfo.h new file mode 100644 index 000000000000..fbfca4b6b85f --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYBaseInfo.h @@ -0,0 +1,70 @@ +//===-- CSKYBaseInfo.h - Top level definitions for CSKY ---*- C++ -*-------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions for +// the CSKY target useful for the compiler back-end and the MC libraries. +// As such, it deliberately does not include references to LLVM core +// code gen types, passes, etc.. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYBASEINFO_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYBASEINFO_H + +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/MC/MCInstrDesc.h" + +namespace llvm { + +// CSKYII - This namespace holds all of the target specific flags that +// instruction info tracks. All definitions must match CSKYInstrFormats.td. +namespace CSKYII { + +enum AddrMode { + AddrModeNone = 0, + AddrMode32B = 1, // ld32.b, ld32.bs, st32.b, st32.bs, +4kb + AddrMode32H = 2, // ld32.h, ld32.hs, st32.h, st32.hs, +8kb + AddrMode32WD = 3, // ld32.w, st32.w, ld32.d, st32.d, +16kb + AddrMode16B = 4, // ld16.b, +32b + AddrMode16H = 5, // ld16.h, +64b + AddrMode16W = 6, // ld16.w, +128b or +1kb + AddrMode32SDF = 7, // flds, fldd, +1kb +}; + +// CSKY Specific MachineOperand Flags. +enum TOF { + MO_None = 0, + MO_ADDR32, + MO_GOT32, + MO_GOTOFF, + MO_PLT32, + MO_ADDR_HI16, + MO_ADDR_LO16, + + // Used to differentiate between target-specific "direct" flags and "bitmask" + // flags. A machine operand can only have one "direct" flag, but can have + // multiple "bitmask" flags. + MO_DIRECT_FLAG_MASK = 15 +}; + +enum { + AddrModeMask = 0x1f, +}; + +} // namespace CSKYII + +namespace CSKYOp { +enum OperandType : unsigned { + OPERAND_BARESYMBOL = MCOI::OPERAND_FIRST_TARGET, + OPERAND_CONSTPOOL +}; +} // namespace CSKYOp + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYBASEINFO_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYFixupKinds.h b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYFixupKinds.h index 917f940fcad4..434fd5481626 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYFixupKinds.h +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYFixupKinds.h @@ -16,6 +16,10 @@ namespace CSKY { enum Fixups { fixup_csky_addr32 = FirstTargetFixupKind, + fixup_csky_addr_hi16, + + fixup_csky_addr_lo16, + fixup_csky_pcrel_imm16_scale2, fixup_csky_pcrel_uimm16_scale4, @@ -24,6 +28,29 @@ enum Fixups { fixup_csky_pcrel_imm18_scale2, + fixup_csky_gotpc, + + fixup_csky_gotoff, + + fixup_csky_got32, + + fixup_csky_got_imm18_scale4, + + fixup_csky_plt32, + + fixup_csky_plt_imm18_scale4, + + fixup_csky_pcrel_imm10_scale2, + + fixup_csky_pcrel_uimm7_scale4, + + fixup_csky_pcrel_uimm8_scale4, + + fixup_csky_doffset_imm18, + + fixup_csky_doffset_imm18_scale2, + + fixup_csky_doffset_imm18_scale4, // Marker fixup_csky_invalid, NumTargetFixupKinds = fixup_csky_invalid - FirstTargetFixupKind diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp index c8920fbb4b4c..7001de999a51 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "CSKYInstPrinter.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -95,6 +96,107 @@ void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, MO.getExpr()->print(O, &MAI); } +void CSKYInstPrinter::printDataSymbol(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + + O << "["; + if (MO.isImm()) + O << MO.getImm(); + else + MO.getExpr()->print(O, &MAI); + O << "]"; +} + +void CSKYInstPrinter::printConstpool(const MCInst *MI, uint64_t Address, + unsigned OpNo, const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + + if (MO.isImm()) { + if (PrintBranchImmAsAddress) { + uint64_t Target = Address + MO.getImm(); + Target &= 0xfffffffc; + O << formatHex(Target); + } else { + O << MO.getImm(); + } + return; + } + + assert(MO.isExpr() && "Unknown operand kind in printConstpool"); + + O << "["; + MO.getExpr()->print(O, &MAI); + O << "]"; +} + +void CSKYInstPrinter::printCSKYSymbolOperand(const MCInst *MI, uint64_t Address, + unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + if (!MO.isImm()) { + return printOperand(MI, OpNo, STI, O); + } + + if (PrintBranchImmAsAddress) { + uint64_t Target = Address + MO.getImm(); + Target &= 0xffffffff; + O << formatHex(Target); + } else { + O << MO.getImm(); + } +} + +void CSKYInstPrinter::printRegisterSeq(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + printRegName(O, MI->getOperand(OpNum).getReg()); + O << "-"; + printRegName(O, MI->getOperand(OpNum + 1).getReg()); +} + +void CSKYInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + auto V = MI->getOperand(OpNum).getImm(); + ListSeparator LS; + + if (V & 0xf) { + O << LS; + printRegName(O, CSKY::R4); + auto Offset = (V & 0xf) - 1; + if (Offset) { + O << "-"; + printRegName(O, CSKY::R4 + Offset); + } + } + + if ((V >> 4) & 0x1) { + O << LS; + printRegName(O, CSKY::R15); + } + + if ((V >> 5) & 0x7) { + O << LS; + printRegName(O, CSKY::R16); + + auto Offset = ((V >> 5) & 0x7) - 1; + + if (Offset) { + O << "-"; + printRegName(O, CSKY::R16 + Offset); + } + } + + if ((V >> 8) & 0x1) { + O << LS; + printRegName(O, CSKY::R28); + } +} + const char *CSKYInstPrinter::getRegisterName(unsigned RegNo) { return getRegisterName(RegNo, ArchRegNames ? CSKY::NoRegAltName : CSKY::ABIRegAltName); diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.h b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.h index a28791a6d8e9..f93a342ec6a3 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.h +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.h @@ -19,6 +19,9 @@ namespace llvm { class CSKYInstPrinter : public MCInstPrinter { +private: + bool ABIRegNames = false; + public: CSKYInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) @@ -43,6 +46,20 @@ public: unsigned OpIdx, unsigned PrintMethodIdx, const MCSubtargetInfo &STI, raw_ostream &O); + void printDataSymbol(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); + void printConstpool(const MCInst *MI, uint64_t Address, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); + void printPSRFlag(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, + raw_ostream &O); + void printRegisterSeq(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); + void printRegisterList(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); + void printCSKYSymbolOperand(const MCInst *MI, uint64_t Address, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); + void printSPAddr(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, + raw_ostream &O); static const char *getRegisterName(unsigned RegNo); static const char *getRegisterName(unsigned RegNo, unsigned AltIdx); }; diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp index 1a5b0225e0b9..1d220b749cb1 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "CSKYMCCodeEmitter.h" +#include "CSKYMCExpr.h" #include "MCTargetDesc/CSKYMCTargetDesc.h" #include "llvm/ADT/Statistic.h" #include "llvm/MC/MCInstBuilder.h" @@ -31,11 +32,46 @@ unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx, return MO.getImm() - 1; } +unsigned +CSKYMCCodeEmitter::getImmOpValueIDLY(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + assert(MO.isImm() && "Unexpected MO type."); + + auto V = (MO.getImm() <= 3) ? 4 : MO.getImm(); + return V - 1; +} + +unsigned +CSKYMCCodeEmitter::getImmOpValueMSBSize(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MSB = MI.getOperand(Idx); + const MCOperand &LSB = MI.getOperand(Idx + 1); + assert(MSB.isImm() && LSB.isImm() && "Unexpected MO type."); + + return MSB.getImm() - LSB.getImm(); +} + +static void writeData(uint32_t Bin, unsigned Size, raw_ostream &OS) { + uint16_t LO16 = static_cast<uint16_t>(Bin); + uint16_t HI16 = static_cast<uint16_t>(Bin >> 16); + + if (Size == 4) + support::endian::write<uint16_t>(OS, HI16, support::little); + + support::endian::write<uint16_t>(OS, LO16, support::little); +} + void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { const MCInstrDesc &Desc = MII.get(MI.getOpcode()); unsigned Size = Desc.getSize(); + + ++MCNumEmitted; + uint32_t Bin = getBinaryCodeForInstr(MI, Fixups, STI); uint16_t LO16 = static_cast<uint16_t>(Bin); @@ -45,7 +81,6 @@ void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, support::endian::write<uint16_t>(OS, HI16, support::little); support::endian::write<uint16_t>(OS, LO16, support::little); - ++MCNumEmitted; // Keep track of the # of mi's emitted. } unsigned @@ -62,6 +97,51 @@ CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, return 0; } +unsigned +CSKYMCCodeEmitter::getRegSeqImmOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + assert(MI.getOperand(Idx).isReg() && "Unexpected MO type."); + assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type."); + + unsigned Ry = MI.getOperand(Idx).getReg(); + unsigned Rz = MI.getOperand(Idx + 1).getImm(); + + unsigned Imm = Ctx.getRegisterInfo()->getEncodingValue(Rz) - + Ctx.getRegisterInfo()->getEncodingValue(Ry); + + return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm); +} + +unsigned +CSKYMCCodeEmitter::getRegisterSeqOpValue(const MCInst &MI, unsigned Op, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + unsigned Reg1 = + Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op).getReg()); + unsigned Reg2 = + Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op + 1).getReg()); + + unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1); + + return Binary; +} + +unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + if (MI.getOperand(Idx).getImm() == 16) + return 0; + else if (MI.getOperand(Idx).getImm() == 24) + return 1; + else if (MI.getOperand(Idx).getImm() == 32) + return 2; + else if (MI.getOperand(Idx).getImm() == 40) + return 3; + else + assert(0); +} + MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const { const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr); @@ -70,6 +150,22 @@ MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const { llvm_unreachable("Unhandled fixup kind!"); case CSKYMCExpr::VK_CSKY_ADDR: return MCFixupKind(CSKY::fixup_csky_addr32); + case CSKYMCExpr::VK_CSKY_ADDR_HI16: + return MCFixupKind(CSKY::fixup_csky_addr_hi16); + case CSKYMCExpr::VK_CSKY_ADDR_LO16: + return MCFixupKind(CSKY::fixup_csky_addr_lo16); + case CSKYMCExpr::VK_CSKY_GOT: + return MCFixupKind(CSKY::fixup_csky_got32); + case CSKYMCExpr::VK_CSKY_GOTPC: + return MCFixupKind(CSKY::fixup_csky_gotpc); + case CSKYMCExpr::VK_CSKY_GOTOFF: + return MCFixupKind(CSKY::fixup_csky_gotoff); + case CSKYMCExpr::VK_CSKY_PLT: + return MCFixupKind(CSKY::fixup_csky_plt32); + case CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4: + return MCFixupKind(CSKY::fixup_csky_plt_imm18_scale4); + case CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4: + return MCFixupKind(CSKY::fixup_csky_got_imm18_scale4); } } diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h index a4c50d992a07..bfba07bcb32a 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h @@ -13,8 +13,8 @@ #ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H #define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H -#include "CSKYMCExpr.h" #include "MCTargetDesc/CSKYFixupKinds.h" +#include "MCTargetDesc/CSKYMCExpr.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" @@ -49,14 +49,40 @@ public: SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { const MCOperand &MO = MI.getOperand(Idx); - assert(MO.isImm() && "Unexpected MO type."); - return (MO.getImm() >> shift); + if (MO.isImm()) + return (MO.getImm() >> shift); + + assert(MO.isExpr() && "Unexpected MO type."); + + MCFixupKind Kind = getTargetFixup(MO.getExpr()); + Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); + return 0; } + unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getOImmOpValue(const MCInst &MI, unsigned Idx, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getImmJMPIX(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { @@ -101,6 +127,21 @@ public: return 0; } + template <llvm::CSKY::Fixups FIXUP> + unsigned getDataSymbolOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + assert(MO.isExpr() && "Unexpected MO type."); + + MCFixupKind Kind = MCFixupKind(FIXUP); + if (MO.getExpr()->getKind() == MCExpr::Target) + Kind = getTargetFixup(MO.getExpr()); + + Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); + return 0; + } + unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp index 59e630f43a42..7987613b0608 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp @@ -26,22 +26,33 @@ StringRef CSKYMCExpr::getVariantKindName(VariantKind Kind) { switch (Kind) { default: llvm_unreachable("Invalid ELF symbol kind"); + case VK_CSKY_None: case VK_CSKY_ADDR: return ""; - case VK_CSKY_PCREL: - return ""; + case VK_CSKY_ADDR_HI16: + return "@HI16"; + case VK_CSKY_ADDR_LO16: + return "@LO16"; + case VK_CSKY_GOT_IMM18_BY4: case VK_CSKY_GOT: return "@GOT"; case VK_CSKY_GOTPC: return "@GOTPC"; case VK_CSKY_GOTOFF: return "@GOTOFF"; + case VK_CSKY_PLT_IMM18_BY4: case VK_CSKY_PLT: return "@PLT"; - case VK_CSKY_TPOFF: + case VK_CSKY_TLSLE: return "@TPOFF"; + case VK_CSKY_TLSIE: + return "@GOTTPOFF"; case VK_CSKY_TLSGD: - return "@TLSGD"; + return "@TLSGD32"; + case VK_CSKY_TLSLDO: + return "@TLSLDO32"; + case VK_CSKY_TLSLDM: + return "@TLSLDM32"; } } @@ -87,7 +98,8 @@ void CSKYMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { switch (getKind()) { default: return; - case VK_CSKY_TPOFF: + case VK_CSKY_TLSLE: + case VK_CSKY_TLSIE: case VK_CSKY_TLSGD: break; } @@ -106,17 +118,20 @@ bool CSKYMCExpr::evaluateAsRelocatableImpl(MCValue &Res, switch (getKind()) { default: return true; - - case VK_CSKY_ADDR: - case VK_CSKY_PCREL: case VK_CSKY_GOT: + case VK_CSKY_GOT_IMM18_BY4: case VK_CSKY_GOTPC: case VK_CSKY_GOTOFF: - case VK_CSKY_TPOFF: + case VK_CSKY_PLT: + case VK_CSKY_PLT_IMM18_BY4: + case VK_CSKY_TLSIE: + case VK_CSKY_TLSLE: case VK_CSKY_TLSGD: + case VK_CSKY_TLSLDO: + case VK_CSKY_TLSLDM: return false; } } return true; -}
\ No newline at end of file +} diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.h b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.h index 06fccada53ce..9e5b4ca7d9bb 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.h +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.h @@ -19,13 +19,20 @@ public: enum VariantKind { VK_CSKY_None, VK_CSKY_ADDR, + VK_CSKY_ADDR_HI16, + VK_CSKY_ADDR_LO16, VK_CSKY_PCREL, VK_CSKY_GOT, + VK_CSKY_GOT_IMM18_BY4, VK_CSKY_GOTPC, VK_CSKY_GOTOFF, VK_CSKY_PLT, - VK_CSKY_TPOFF, + VK_CSKY_PLT_IMM18_BY4, + VK_CSKY_TLSIE, + VK_CSKY_TLSLE, VK_CSKY_TLSGD, + VK_CSKY_TLSLDO, + VK_CSKY_TLSLDM, VK_CSKY_Invalid }; diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp index 169e1e14eb0a..0901c0993607 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp @@ -19,7 +19,7 @@ #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/TargetRegistry.h" #define GET_INSTRINFO_MC_DESC #include "CSKYGenInstrInfo.inc" diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h index da8a3b63a2f9..25bbd635fc58 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h @@ -45,4 +45,7 @@ MCCodeEmitter *createCSKYMCCodeEmitter(const MCInstrInfo &MCII, #define GET_INSTRINFO_ENUM #include "CSKYGenInstrInfo.inc" +#define GET_SUBTARGETINFO_ENUM +#include "CSKYGenSubtargetInfo.inc" + #endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCTARGETDESC_H diff --git a/contrib/llvm-project/llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp b/contrib/llvm-project/llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp index 1af2e672ff42..40b7d493652d 100644 --- a/contrib/llvm-project/llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp +++ b/contrib/llvm-project/llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "TargetInfo/CSKYTargetInfo.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/TargetRegistry.h" using namespace llvm; Target &llvm::getTheCSKYTarget() { |