aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/CSKY
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/CSKY')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp873
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.h27
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKY.td87
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp58
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYAsmPrinter.h40
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.h63
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYCallingConv.td82
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp57
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.h38
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp75
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.cpp346
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.h69
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats.td221
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrFormats16Instr.td219
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp25
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.h36
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td644
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo16Instr.td452
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.cpp117
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.h35
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h62
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp95
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.h45
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYRegisterInfo.td15
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.cpp74
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYSubtarget.h120
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp41
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/CSKYTargetMachine.h8
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp49
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h3
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYBaseInfo.h70
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYFixupKinds.h27
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp102
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.h17
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp98
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h47
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp35
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.h9
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h3
-rw-r--r--contrib/llvm-project/llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp2
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() {