[llvm] 582836f - [CSKY] Enhance asm parser and relocation fixup for some special symbol address instruction
Zi Xuan Wu via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 23 23:14:54 PDT 2022
Author: Zi Xuan Wu
Date: 2022-03-24T14:14:04+08:00
New Revision: 582836faafcb458161947a72df27752fe5f76171
URL: https://github.com/llvm/llvm-project/commit/582836faafcb458161947a72df27752fe5f76171
DIFF: https://github.com/llvm/llvm-project/commit/582836faafcb458161947a72df27752fe5f76171.diff
LOG: [CSKY] Enhance asm parser and relocation fixup for some special symbol address instruction
Add processing of parsing and emiting lrw/jsri/jmpi instruction, including related fixup and relocation.
Add relax support about pseudo instructions such as jbr/jbsr.
Add objdump format support like arm in llvm-objdump.
Added:
llvm/lib/Target/CSKY/CSKYInstrAlias.td
llvm/test/MC/CSKY/3e3r1.s
llvm/test/MC/CSKY/801.s
llvm/test/MC/CSKY/branch-relax-801.s
llvm/test/MC/CSKY/branch-relax-803.s
llvm/test/MC/CSKY/bsr.s
llvm/test/MC/CSKY/jmpi.s
llvm/test/MC/CSKY/jsri.s
llvm/test/MC/CSKY/lrs.s
llvm/test/MC/CSKY/lrw.s
llvm/test/MC/CSKY/tls_gd.s
llvm/test/MC/CSKY/tls_ie.s
llvm/test/MC/CSKY/tls_ld.s
llvm/test/MC/CSKY/tls_le.s
Modified:
llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp
llvm/lib/Target/CSKY/CSKYInstrInfo.td
llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp
llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp
llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h
llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp b/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp
index aca05ee8fcfa5..f67147a60c61e 100644
--- a/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp
+++ b/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp
@@ -86,6 +86,9 @@ class CSKYAsmParser : public MCTargetAsmParser {
bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
MCStreamer &Out);
+ bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
+ bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
+ bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
CSKYTargetStreamer &getTargetStreamer() {
assert(getParser().getStreamer().getTargetStreamer() &&
@@ -128,7 +131,11 @@ class CSKYAsmParser : public MCTargetAsmParser {
MCAsmParserExtension::Initialize(Parser);
+ // Cache the MCRegisterInfo.
+ MRI = getContext().getRegisterInfo();
+
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+ getTargetStreamer().emitTargetAttributes(STI);
}
};
@@ -813,6 +820,96 @@ bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
llvm_unreachable("Unknown match type detected!");
}
+bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
+ Inst.setLoc(IDLoc);
+
+ unsigned Opcode;
+ MCOperand Op;
+ if (Inst.getOpcode() == CSKY::PseudoLRW16)
+ Opcode = CSKY::LRW16;
+ else
+ Opcode = CSKY::LRW32;
+
+ if (Inst.getOperand(1).isImm()) {
+ if (isUInt<8>(Inst.getOperand(1).getImm()) &&
+ Inst.getOperand(0).getReg() <= CSKY::R7) {
+ Opcode = CSKY::MOVI16;
+ } else if (getSTI().getFeatureBits()[CSKY::HasE2] &&
+ isUInt<16>(Inst.getOperand(1).getImm())) {
+ Opcode = CSKY::MOVI32;
+ } else {
+ auto *Expr = getTargetStreamer().addConstantPoolEntry(
+ MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),
+ Inst.getLoc());
+ Inst.erase(std::prev(Inst.end()));
+ Inst.addOperand(MCOperand::createExpr(Expr));
+ }
+ } else {
+ const MCExpr *AdjustExpr = nullptr;
+ if (const CSKYMCExpr *CSKYExpr =
+ dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) {
+ if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD ||
+ CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE ||
+ CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) {
+ MCSymbol *Dot = getContext().createNamedTempSymbol();
+ Out.emitLabel(Dot);
+ AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());
+ }
+ }
+ auto *Expr = getTargetStreamer().addConstantPoolEntry(
+ Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);
+ Inst.erase(std::prev(Inst.end()));
+ Inst.addOperand(MCOperand::createExpr(Expr));
+ }
+
+ Inst.setOpcode(Opcode);
+
+ Out.emitInstruction(Inst, getSTI());
+ return false;
+}
+
+bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
+ Inst.setLoc(IDLoc);
+
+ if (Inst.getOperand(0).isImm()) {
+ const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
+ MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
+ Inst.getLoc());
+ Inst.setOpcode(CSKY::JSRI32);
+ Inst.erase(std::prev(Inst.end()));
+ Inst.addOperand(MCOperand::createExpr(Expr));
+ } else {
+ const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
+ Inst.getOperand(0).getExpr(), Inst.getLoc());
+ Inst.setOpcode(CSKY::JBSR32);
+ Inst.addOperand(MCOperand::createExpr(Expr));
+ }
+
+ Out.emitInstruction(Inst, getSTI());
+ return false;
+}
+
+bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
+ Inst.setLoc(IDLoc);
+
+ if (Inst.getOperand(0).isImm()) {
+ const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
+ MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
+ Inst.getLoc());
+ Inst.setOpcode(CSKY::JMPI32);
+ Inst.erase(std::prev(Inst.end()));
+ Inst.addOperand(MCOperand::createExpr(Expr));
+ } else {
+ const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
+ Inst.getOperand(0).getExpr(), Inst.getLoc());
+ Inst.setOpcode(CSKY::JBR32);
+ Inst.addOperand(MCOperand::createExpr(Expr));
+ }
+
+ Out.emitInstruction(Inst, getSTI());
+ return false;
+}
+
bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
OperandVector &Operands,
MCStreamer &Out) {
@@ -870,6 +967,28 @@ bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Inst.erase(std::next(Inst.begin()));
Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
break;
+ case CSKY::PseudoLRW16:
+ case CSKY::PseudoLRW32:
+ return processLRW(Inst, IDLoc, Out);
+ case CSKY::PseudoJSRI32:
+ return processJSRI(Inst, IDLoc, Out);
+ case CSKY::PseudoJMPI32:
+ return processJMPI(Inst, IDLoc, Out);
+ case CSKY::JBSR32:
+ case CSKY::JBR16:
+ case CSKY::JBT16:
+ case CSKY::JBF16:
+ case CSKY::JBR32:
+ case CSKY::JBT32:
+ case CSKY::JBF32:
+ unsigned Num = Inst.getNumOperands() - 1;
+ assert(Inst.getOperand(Num).isExpr());
+
+ const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
+ Inst.getOperand(Num).getExpr(), Inst.getLoc());
+
+ Inst.addOperand(MCOperand::createExpr(Expr));
+ break;
}
emitToStreamer(Out, Inst);
diff --git a/llvm/lib/Target/CSKY/CSKYInstrAlias.td b/llvm/lib/Target/CSKY/CSKYInstrAlias.td
new file mode 100644
index 0000000000000..e3c0538e752e6
--- /dev/null
+++ b/llvm/lib/Target/CSKY/CSKYInstrAlias.td
@@ -0,0 +1,38 @@
+//===-- CSKYInstrAlias.td - Target Description for 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 file describes the CSKY instructions alias.
+//
+//===----------------------------------------------------------------------===//
+
+def : InstAlias<"nop", (MOV16 R0, R0)>;
+def : InstAlias<"nop", (MOV32 R0, R0)>, Requires<[iHasE2]>;
+
+def : InstAlias<"bgeni16 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>;
+def : InstAlias<"bgeni32 $dst, $imm", (BGENI GPR:$dst, uimm5:$imm)>;
+
+def : InstAlias<"bsr $dst", (BSR32 call_symbol:$dst)>;
+
+def : InstAlias<"grs\t$rz, $offset", (GRS32 GPR:$rz, bare_symbol:$offset)>;
+
+def : InstAlias<"jbsr\t$src1", (JBSR32 call_symbol:$src1)>;
+
+def : InstAlias<"jbr $dst", (JBR16 br_symbol_16bit:$dst)>;
+def : InstAlias<"jbt $dst", (JBT16 C, br_symbol_16bit:$dst)>;
+def : InstAlias<"jbf $dst", (JBF16 C, br_symbol_16bit:$dst)>;
+
+def : InstAlias<"lrw $rz, $src", (PseudoLRW16 mGPR:$rz, bare_symbol:$src)>;
+def : InstAlias<"lrw $rz, $src", (LRW16 mGPR:$rz, constpool_symbol_16bit:$src)>;
+def : InstAlias<"lrw $rz, $src", (PseudoLRW32 GPR:$rz, bare_symbol:$src)>;
+def : InstAlias<"lrw $rz, $src", (LRW32 GPR:$rz, constpool_symbol:$src)>;
+
+def : InstAlias<"jsri $dst", (PseudoJSRI32 call_symbol:$dst)>;
+def : InstAlias<"jsri $dst", (JSRI32 constpool_symbol:$dst)>;
+
+def : InstAlias<"jmpi $dst", (PseudoJMPI32 br_symbol:$dst)>;
+def : InstAlias<"jmpi $dst", (JMPI32 constpool_symbol:$dst)>;
\ No newline at end of file
diff --git a/llvm/lib/Target/CSKY/CSKYInstrInfo.td b/llvm/lib/Target/CSKY/CSKYInstrInfo.td
index a782efe7f4f42..e3edf8280c75c 100644
--- a/llvm/lib/Target/CSKY/CSKYInstrInfo.td
+++ b/llvm/lib/Target/CSKY/CSKYInstrInfo.td
@@ -709,8 +709,6 @@ let Predicates= [iHasE2] in {
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
@@ -779,8 +777,6 @@ def BNEZAD32 : CSKY32Inst<AddrModeNone, 0x3a,
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;
@@ -804,7 +800,6 @@ 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",
@@ -1291,8 +1286,6 @@ let Predicates = [iHasE2] in {
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;
@@ -1338,18 +1331,13 @@ 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),
@@ -1362,3 +1350,4 @@ def CONSTPOOL_ENTRY : CSKYPseudo<(outs),
include "CSKYInstrInfo16Instr.td"
include "CSKYInstrInfoF1.td"
include "CSKYInstrInfoF2.td"
+include "CSKYInstrAlias.td"
\ No newline at end of file
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
index daa655416c476..215b453739a3e 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
@@ -88,6 +88,13 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
switch (Fixup.getTargetKind()) {
default:
llvm_unreachable("Unknown fixup kind!");
+ case CSKY::fixup_csky_got32:
+ case CSKY::fixup_csky_got_imm18_scale4:
+ case CSKY::fixup_csky_gotoff:
+ case CSKY::fixup_csky_gotpc:
+ case CSKY::fixup_csky_plt32:
+ case CSKY::fixup_csky_plt_imm18_scale4:
+ llvm_unreachable("Relocation should be unconditionally forced\n");
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
@@ -123,6 +130,71 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
return (Value >> 1) & 0x3ffff;
+ case CSKY::fixup_csky_pcrel_uimm8_scale4: {
+ if (!isUIntN(10, Value))
+ Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
+ if (Value & 0x3)
+ Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
+
+ unsigned IMM4L = (Value >> 2) & 0xf;
+ unsigned IMM4H = (Value >> 6) & 0xf;
+
+ Value = (IMM4H << 21) | (IMM4L << 4);
+ return Value;
+ }
+ case CSKY::fixup_csky_pcrel_imm10_scale2:
+ if (!isIntN(11, Value))
+ Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
+ if (Value & 0x1)
+ Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
+
+ return (Value >> 1) & 0x3ff;
+ case CSKY::fixup_csky_pcrel_uimm7_scale4:
+ if (!isUIntN(9, Value))
+ Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
+ if (Value & 0x3)
+ Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
+
+ if ((Value & 0xff) <= 0b111111100) {
+ unsigned IMM5L = (Value >> 2) & 0x1f;
+ unsigned IMM2H = (Value >> 7) & 0x3;
+
+ Value = (1 << 12) | (IMM2H << 8) | IMM5L;
+ } else {
+ unsigned IMM5L = (!Value >> 2) & 0x1f;
+ unsigned IMM2H = (!Value >> 7) & 0x3;
+
+ Value = (IMM2H << 8) | IMM5L;
+ }
+
+ return Value & 0xffff;
+ }
+}
+
+bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
+ bool Resolved, uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout,
+ const bool WasForced) const {
+ // Return true if the symbol is actually unresolved.
+ // Resolved could be always false when shouldForceRelocation return true.
+ // We use !WasForced to indicate that the symbol is unresolved and not forced
+ // by shouldForceRelocation.
+ if (!Resolved && !WasForced)
+ return true;
+
+ int64_t Offset = int64_t(Value);
+ switch (Fixup.getTargetKind()) {
+ default:
+ return false;
+ case CSKY::fixup_csky_pcrel_imm10_scale2:
+ return !isShiftedInt<10, 1>(Offset);
+ case CSKY::fixup_csky_pcrel_imm16_scale2:
+ return !isShiftedInt<16, 1>(Offset);
+ case CSKY::fixup_csky_pcrel_imm26_scale2:
+ return !isShiftedInt<26, 1>(Offset);
+ case CSKY::fixup_csky_pcrel_uimm7_scale4:
+ return !isShiftedUInt<8, 2>(Offset);
}
}
@@ -166,6 +238,50 @@ void CSKYAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
}
}
+bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const {
+ switch (Inst.getOpcode()) {
+ default:
+ return false;
+ case CSKY::JBR32:
+ case CSKY::JBT32:
+ case CSKY::JBF32:
+ case CSKY::JBSR32:
+ if (!STI.getFeatureBits()[CSKY::Has2E3])
+ return false;
+ return true;
+ case CSKY::JBR16:
+ case CSKY::JBT16:
+ case CSKY::JBF16:
+ case CSKY::LRW16:
+ case CSKY::BR16:
+ return true;
+ }
+}
+
+bool CSKYAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
+ const MCFixup &Fixup,
+ const MCValue &Target) {
+ if (Fixup.getKind() >= FirstLiteralRelocationKind)
+ return true;
+ switch (Fixup.getTargetKind()) {
+ default:
+ break;
+ case CSKY::fixup_csky_got32:
+ case CSKY::fixup_csky_got_imm18_scale4:
+ case CSKY::fixup_csky_gotoff:
+ case CSKY::fixup_csky_gotpc:
+ case CSKY::fixup_csky_plt32:
+ case CSKY::fixup_csky_plt_imm18_scale4:
+ case CSKY::fixup_csky_doffset_imm18:
+ case CSKY::fixup_csky_doffset_imm18_scale2:
+ case CSKY::fixup_csky_doffset_imm18_scale4:
+ return true;
+ }
+
+ return false;
+}
+
bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const {
@@ -174,23 +290,62 @@ bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
void CSKYAsmBackend::relaxInstruction(MCInst &Inst,
const MCSubtargetInfo &STI) const {
- llvm_unreachable("CSKYAsmBackend::relaxInstruction() unimplemented");
-}
+ MCInst Res;
-bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
- const MCSubtargetInfo *STI) const {
- if (Count % 2)
- return false;
+ switch (Inst.getOpcode()) {
+ default:
+ Inst.dump();
+ llvm_unreachable("Opcode not expected!");
+ case CSKY::LRW16:
+ Res.setOpcode(CSKY::LRW32);
+ Res.addOperand(Inst.getOperand(0));
+ Res.addOperand(Inst.getOperand(1));
+ break;
+ case CSKY::BR16:
+ Res.setOpcode(CSKY::BR32);
+ Res.addOperand(Inst.getOperand(0));
+ break;
+ case CSKY::JBSR32:
+ Res.setOpcode(CSKY::JSRI32);
+ Res.addOperand(Inst.getOperand(1));
+ break;
+ case CSKY::JBR32:
+ Res.setOpcode(CSKY::JMPI32);
+ Res.addOperand(Inst.getOperand(1));
+ break;
+ case CSKY::JBT32:
+ case CSKY::JBF32:
+ Res.setOpcode(Inst.getOpcode() == CSKY::JBT32 ? CSKY::JBT_E : CSKY::JBF_E);
+ Res.addOperand(Inst.getOperand(0));
+ Res.addOperand(Inst.getOperand(1));
+ Res.addOperand(Inst.getOperand(2));
+ break;
+ case CSKY::JBR16:
+ Res.setOpcode(CSKY::JBR32);
+ Res.addOperand(Inst.getOperand(0));
+ Res.addOperand(Inst.getOperand(1));
+ break;
+ case CSKY::JBT16:
+ case CSKY::JBF16:
+ // ck801
+ unsigned opcode;
+ if (STI.getFeatureBits()[CSKY::HasE2])
+ opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT32 : CSKY::JBF32;
+ else
+ opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT_E : CSKY::JBF_E;
- // MOV32 r0, r0
- while (Count >= 4) {
- OS.write("\xc4\x00\x48\x20", 4);
- Count -= 4;
+ Res.setOpcode(opcode);
+ Res.addOperand(Inst.getOperand(0));
+ Res.addOperand(Inst.getOperand(1));
+ Res.addOperand(Inst.getOperand(2));
+ break;
}
- // MOV16 r0, r0
- if (Count)
- OS.write("\x6c\x03", 2);
+ Inst = std::move(Res);
+}
+bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
+ const MCSubtargetInfo *STI) const {
+ OS.write_zeros(Count);
return true;
}
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
index 87503439fe1a0..09b3ce6cc82be 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
@@ -40,9 +40,21 @@ class CSKYAsmBackend : public MCAsmBackend {
void relaxInstruction(MCInst &Inst,
const MCSubtargetInfo &STI) const override;
+ bool mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const override;
+
+ bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
+ uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout,
+ const bool WasForced) const override;
+
bool writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const override;
+ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target) override;
+
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override;
};
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp
index 1636326322908..321a4145b207b 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp
@@ -6,7 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include "CSKYFixupKinds.h"
#include "CSKYMCTargetDesc.h"
+#include "CSKYMCExpr.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCObjectWriter.h"
@@ -33,10 +35,111 @@ unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx,
const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
- // Determine the type of the relocation.
- switch ((unsigned)Fixup.getKind()) {
+ const MCExpr *Expr = Fixup.getValue();
+ // Determine the type of the relocation
+ unsigned Kind = Fixup.getTargetKind();
+ MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
+
+ if (IsPCRel) {
+ switch (Kind) {
+ default:
+ LLVM_DEBUG(dbgs() << "Unknown Kind1 = " << Kind);
+ Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
+ return ELF::R_CKCORE_NONE;
+ case FK_Data_4:
+ case FK_PCRel_4:
+ return ELF::R_CKCORE_PCREL32;
+ case CSKY::fixup_csky_pcrel_uimm16_scale4:
+ return ELF::R_CKCORE_PCREL_IMM16_4;
+ case CSKY::fixup_csky_pcrel_uimm8_scale4:
+ return ELF::R_CKCORE_PCREL_IMM8_4;
+ case CSKY::fixup_csky_pcrel_imm26_scale2:
+ return ELF::R_CKCORE_PCREL_IMM26_2;
+ case CSKY::fixup_csky_pcrel_imm18_scale2:
+ return ELF::R_CKCORE_PCREL_IMM18_2;
+ case CSKY::fixup_csky_pcrel_imm16_scale2:
+ return ELF::R_CKCORE_PCREL_IMM16_2;
+ case CSKY::fixup_csky_pcrel_imm10_scale2:
+ return ELF::R_CKCORE_PCREL_IMM10_2;
+ case CSKY::fixup_csky_pcrel_uimm7_scale4:
+ return ELF::R_CKCORE_PCREL_IMM7_4;
+ }
+ }
+
+ switch (Kind) {
default:
- llvm_unreachable("invalid fixup kind!");
+ LLVM_DEBUG(dbgs() << "Unknown Kind2 = " << Kind);
+ Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
+ return ELF::R_CKCORE_NONE;
+ case FK_Data_1:
+ Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
+ return ELF::R_CKCORE_NONE;
+ case FK_Data_2:
+ Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
+ return ELF::R_CKCORE_NONE;
+ case FK_Data_4:
+ if (Expr->getKind() == MCExpr::Target) {
+ auto TK = cast<CSKYMCExpr>(Expr)->getKind();
+ if (TK == CSKYMCExpr::VK_CSKY_ADDR)
+ return ELF::R_CKCORE_ADDR32;
+ if (TK == CSKYMCExpr::VK_CSKY_GOT)
+ return ELF::R_CKCORE_GOT32;
+ if (TK == CSKYMCExpr::VK_CSKY_GOTOFF)
+ return ELF::R_CKCORE_GOTOFF;
+ if (TK == CSKYMCExpr::VK_CSKY_PLT)
+ return ELF::R_CKCORE_PLT32;
+ if (TK == CSKYMCExpr::VK_CSKY_TLSIE)
+ return ELF::R_CKCORE_TLS_IE32;
+ if (TK == CSKYMCExpr::VK_CSKY_TLSLE)
+ return ELF::R_CKCORE_TLS_LE32;
+ if (TK == CSKYMCExpr::VK_CSKY_TLSGD)
+ return ELF::R_CKCORE_TLS_GD32;
+ if (TK == CSKYMCExpr::VK_CSKY_TLSLDM)
+ return ELF::R_CKCORE_TLS_LDM32;
+ if (TK == CSKYMCExpr::VK_CSKY_TLSLDO)
+ return ELF::R_CKCORE_TLS_LDO32;
+ if (TK == CSKYMCExpr::VK_CSKY_GOTPC)
+ return ELF::R_CKCORE_GOTPC;
+ if (TK == CSKYMCExpr::VK_CSKY_None)
+ return ELF::R_CKCORE_ADDR32;
+
+ LLVM_DEBUG(dbgs() << "Unknown FK_Data_4 TK = " << TK);
+ Ctx.reportError(Fixup.getLoc(), "unknown target FK_Data_4");
+ } else {
+ switch (Modifier) {
+ default:
+ Ctx.reportError(Fixup.getLoc(),
+ "invalid fixup for 4-byte data relocation");
+ return ELF::R_CKCORE_NONE;
+ case MCSymbolRefExpr::VK_GOT:
+ return ELF::R_CKCORE_GOT32;
+ case MCSymbolRefExpr::VK_GOTOFF:
+ return ELF::R_CKCORE_GOTOFF;
+ case MCSymbolRefExpr::VK_PLT:
+ return ELF::R_CKCORE_PLT32;
+ case MCSymbolRefExpr::VK_None:
+ return ELF::R_CKCORE_ADDR32;
+ }
+ }
+ case FK_Data_8:
+ Ctx.reportError(Fixup.getLoc(), "8-byte data relocations not supported");
+ return ELF::R_CKCORE_NONE;
+ case CSKY::fixup_csky_addr32:
+ return ELF::R_CKCORE_ADDR32;
+ case CSKY::fixup_csky_addr_hi16:
+ return ELF::R_CKCORE_ADDR_HI16;
+ case CSKY::fixup_csky_addr_lo16:
+ return ELF::R_CKCORE_ADDR_LO16;
+ case CSKY::fixup_csky_doffset_imm18:
+ return ELF::R_CKCORE_DOFFSET_IMM18;
+ case CSKY::fixup_csky_doffset_imm18_scale2:
+ return ELF::R_CKCORE_DOFFSET_IMM18_2;
+ case CSKY::fixup_csky_doffset_imm18_scale4:
+ return ELF::R_CKCORE_DOFFSET_IMM18_4;
+ case CSKY::fixup_csky_got_imm18_scale4:
+ return ELF::R_CKCORE_GOT_IMM18_4;
+ case CSKY::fixup_csky_plt_imm18_scale4:
+ return ELF::R_CKCORE_PLT_IMM18_4;
}
}
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp
index 29b91173bc117..540f901fd479d 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp
@@ -67,15 +67,170 @@ static void writeData(uint32_t Bin, unsigned Size, raw_ostream &OS) {
support::endian::write<uint16_t>(OS, LO16, support::little);
}
+void CSKYMCCodeEmitter::expandJBTF(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ MCInst TmpInst;
+
+ uint32_t Binary;
+
+ TmpInst =
+ MCInstBuilder(MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)
+ .addOperand(MI.getOperand(0))
+ .addImm(6);
+ Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
+ writeData(Binary, 2, OS);
+
+ if (!STI.getFeatureBits()[CSKY::Has2E3])
+ TmpInst = MCInstBuilder(CSKY::BR32)
+ .addOperand(MI.getOperand(1))
+ .addOperand(MI.getOperand(2));
+ else
+ TmpInst = MCInstBuilder(CSKY::JMPI32).addOperand(MI.getOperand(2));
+ Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
+ Fixups[Fixups.size() - 1].setOffset(2);
+ writeData(Binary, 4, OS);
+}
+
+void CSKYMCCodeEmitter::expandNEG(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ MCInst TmpInst;
+ uint32_t Binary;
+ unsigned Size = MI.getOpcode() == CSKY::NEG32 ? 4 : 2;
+
+ TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1));
+ Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
+ writeData(Binary, Size, OS);
+
+ TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(0))
+ .addImm(1);
+ Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
+ writeData(Binary, Size, OS);
+}
+
+void CSKYMCCodeEmitter::expandRSUBI(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ MCInst TmpInst;
+ uint32_t Binary;
+ unsigned Size = MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;
+
+ TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1));
+ Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
+ writeData(Binary, Size, OS);
+
+ TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(0))
+ .addImm(MI.getOperand(2).getImm() + 1);
+ Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
+ writeData(Binary, Size, OS);
+}
+
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();
+ MCInst TmpInst;
+
+ switch (MI.getOpcode()) {
+ default:
+ TmpInst = MI;
+ break;
+ case CSKY::JBT_E:
+ case CSKY::JBF_E:
+ expandJBTF(MI, OS, Fixups, STI);
+ MCNumEmitted += 2;
+ return;
+ case CSKY::NEG32:
+ case CSKY::NEG16:
+ expandNEG(MI, OS, Fixups, STI);
+ MCNumEmitted += 2;
+ return;
+ case CSKY::RSUBI32:
+ case CSKY::RSUBI16:
+ expandRSUBI(MI, OS, Fixups, STI);
+ MCNumEmitted += 2;
+ return;
+ case CSKY::JBSR32:
+ TmpInst = MCInstBuilder(CSKY::BSR32).addOperand(MI.getOperand(0));
+ break;
+ case CSKY::JBR16:
+ TmpInst = MCInstBuilder(CSKY::BR16).addOperand(MI.getOperand(0));
+ break;
+ case CSKY::JBR32:
+ TmpInst = MCInstBuilder(CSKY::BR32).addOperand(MI.getOperand(0));
+ break;
+ case CSKY::JBT16:
+ TmpInst = MCInstBuilder(CSKY::BT16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1));
+ break;
+ case CSKY::JBT32:
+ TmpInst = MCInstBuilder(CSKY::BT32)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1));
+ break;
+ case CSKY::JBF16:
+ TmpInst = MCInstBuilder(CSKY::BF16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1));
+ break;
+ case CSKY::JBF32:
+ TmpInst = MCInstBuilder(CSKY::BF32)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1));
+ break;
+ case CSKY::LRW32_Gen:
+ TmpInst = MCInstBuilder(CSKY::LRW32)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(2));
+ break;
+ case CSKY::LRW16_Gen:
+ TmpInst = MCInstBuilder(CSKY::LRW16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(2));
+ break;
+ case CSKY::CMPLEI32:
+ TmpInst = MCInstBuilder(CSKY::CMPLTI32)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1))
+ .addImm(MI.getOperand(2).getImm() + 1);
+ break;
+ case CSKY::CMPLEI16:
+ TmpInst = MCInstBuilder(CSKY::CMPLTI16)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1))
+ .addImm(MI.getOperand(2).getImm() + 1);
+ break;
+ case CSKY::ROTRI32:
+ TmpInst = MCInstBuilder(CSKY::ROTLI32)
+ .addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1))
+ .addImm(32 - MI.getOperand(2).getImm());
+ break;
+ case CSKY::BGENI:
+ auto V = 1 << MI.getOperand(1).getImm();
+ TmpInst =
+ MCInstBuilder(CSKY::MOVI32).addOperand(MI.getOperand(0)).addImm(V);
+ break;
+ }
+
++MCNumEmitted;
- uint32_t Bin = getBinaryCodeForInstr(MI, Fixups, STI);
+ uint32_t Bin = getBinaryCodeForInstr(TmpInst, Fixups, STI);
uint16_t LO16 = static_cast<uint16_t>(Bin);
uint16_t HI16 = static_cast<uint16_t>(Bin >> 16);
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h
index 0720d33920200..128430197cc53 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h
@@ -171,6 +171,16 @@ class CSKYMCCodeEmitter : public MCCodeEmitter {
Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
return 0;
}
+
+ void expandJBTF(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+ void expandNEG(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+ void expandRSUBI(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
};
} // namespace llvm
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp
index c41a20060e484..1a69dc8acde05 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp
@@ -19,6 +19,7 @@
#include "CSKYTargetStreamer.h"
#include "TargetInfo/CSKYTargetInfo.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -107,6 +108,49 @@ static MCTargetStreamer *createCSKYNullTargetStreamer(MCStreamer &S) {
return new CSKYTargetStreamer(S);
}
+namespace {
+
+class CSKYMCInstrAnalysis : public MCInstrAnalysis {
+public:
+ explicit CSKYMCInstrAnalysis(const MCInstrInfo *Info)
+ : MCInstrAnalysis(Info) {}
+
+ bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
+ uint64_t &Target) const override {
+ if (isConditionalBranch(Inst) || isUnconditionalBranch(Inst)) {
+ int64_t Imm;
+ Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();
+ Target = Addr + Imm;
+ return true;
+ }
+
+ if (Inst.getOpcode() == CSKY::BSR32) {
+ Target = Addr + Inst.getOperand(0).getImm();
+ return true;
+ }
+
+ switch (Inst.getOpcode()) {
+ default:
+ return false;
+ case CSKY::LRW16:
+ case CSKY::LRW32:
+ case CSKY::JSRI32:
+ case CSKY::JMPI32:
+ int64_t Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();
+ Target = ((Addr + Imm) & 0xFFFFFFFC);
+ return true;
+ }
+
+ return false;
+ }
+};
+
+} // end anonymous namespace
+
+static MCInstrAnalysis *createCSKYInstrAnalysis(const MCInstrInfo *Info) {
+ return new CSKYMCInstrAnalysis(Info);
+}
+
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() {
auto &CSKYTarget = getTheCSKYTarget();
TargetRegistry::RegisterMCAsmBackend(CSKYTarget, createCSKYAsmBackend);
@@ -125,4 +169,5 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() {
// Register the null target streamer.
TargetRegistry::RegisterNullTargetStreamer(CSKYTarget,
createCSKYNullTargetStreamer);
+ TargetRegistry::RegisterMCInstrAnalysis(CSKYTarget, createCSKYInstrAnalysis);
}
diff --git a/llvm/test/MC/CSKY/3e3r1.s b/llvm/test/MC/CSKY/3e3r1.s
new file mode 100644
index 0000000000000..2aebc90083c05
--- /dev/null
+++ b/llvm/test/MC/CSKY/3e3r1.s
@@ -0,0 +1,22 @@
+# RUN: llvm-mc %s -triple=csky -show-encoding -csky-no-aliases -mattr=+3e3r1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+3e3r1 < %s \
+# RUN: | llvm-objdump --mattr=+3e3r1 -M no-aliases -M abi-names -d -r - \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+
+
+# CHECK-ASM-AND-OBJ: mul.s32 a3, l0, a1
+# CHECK-ASM: encoding: [0x24,0xf8,0x03,0x82]
+mul.s32 a3, l0, a1
+
+# CHECK-ASM-AND-OBJ: mul.u32 a3, l0, a1
+# CHECK-ASM: encoding: [0x24,0xf8,0x03,0x80]
+mul.u32 a3, l0, a1
+
+# CHECK-ASM-AND-OBJ: mula.s32 a3, l0, a1
+# CHECK-ASM: encoding: [0x24,0xf8,0x83,0x82]
+mula.s32 a3, l0, a1
+
+# CHECK-ASM-AND-OBJ: mula.u32 a3, l0, a1
+# CHECK-ASM: encoding: [0x24,0xf8,0x83,0x80]
+mula.u32 a3, l0, a1
\ No newline at end of file
diff --git a/llvm/test/MC/CSKY/801.s b/llvm/test/MC/CSKY/801.s
new file mode 100644
index 0000000000000..9b3d5ce394fc4
--- /dev/null
+++ b/llvm/test/MC/CSKY/801.s
@@ -0,0 +1,19 @@
+# RUN: llvm-mc %s -triple=csky -show-encoding -csky-no-aliases -mattr=+e1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+e1 < %s \
+# RUN: | llvm-objdump --mattr=+e1 -M no-aliases -d -r - \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: ipush
+# CHECK-ASM: encoding: [0x62,0x14]
+ipush16
+
+# CHECK-ASM-AND-OBJ: ipop
+# CHECK-ASM: encoding: [0x63,0x14]
+ipop16
+
+# RUN: not llvm-mc -triple csky -mattr=+e1 --defsym=ERR=1 < %s 2>&1 | FileCheck %s
+
+.ifdef ERR
+ipush16 1 # CHECK: :[[#@LINE]]:9: error: invalid operand for instruction
+.endif
diff --git a/llvm/test/MC/CSKY/branch-relax-801.s b/llvm/test/MC/CSKY/branch-relax-801.s
new file mode 100644
index 0000000000000..87a51cd947402
--- /dev/null
+++ b/llvm/test/MC/CSKY/branch-relax-801.s
@@ -0,0 +1,44 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mcpu=ck801 < %s \
+# RUN: | llvm-objdump --mattr=+e1 --no-show-raw-insn -M no-aliases -d -r - \
+# RUN: | FileCheck -check-prefixes=CHECK-OBJ-CK801 %s
+# RUN: llvm-mc -filetype=obj -triple=csky -mcpu=ck802 < %s \
+# RUN: | llvm-objdump --mattr=+e2 --no-show-raw-insn -M no-aliases -d -r - \
+# RUN: | FileCheck -check-prefixes=CHECK-OBJ-CK802 %s
+
+# CHECK-OBJ-CK801: 0: addu16 r1, r2, r3
+# CHECK-OBJ-CK801-NEXT: 2: bt16 0x8
+# CHECK-OBJ-CK801-NEXT: 4: br32 0x4bc
+# CHECK-OBJ-CK801-NEXT: 8: addu16 r3, r2, r1
+# CHECK-OBJ-CK801: 4ba: addu16 r1, r2, r3
+# CHECK-OBJ-CK801-NEXT: 4bc: bf16 0x4c2
+# CHECK-OBJ-CK801-NEXT: 4be: br32 0x2
+# CHECK-OBJ-CK801-NEXT: 4c2: br32 0x2
+# CHECK-OBJ-CK801-NEXT: 4c6: addu16 r3, r2, r1
+# CHECK-OBJ-CK801-NEXT: 4c8: br16 0x4ca
+
+# CHECK-OBJ-CK802: 0: addu16 r1, r2, r3
+# CHECK-OBJ-CK802-NEXT: 2: bf32 0x96a
+# CHECK-OBJ-CK802-NEXT: 6: addu16 r3, r2, r1
+# CHECK-OBJ-CK802: 968: addu16 r1, r2, r3
+# CHECK-OBJ-CK802-NEXT: 96a: bt32 0x2
+# CHECK-OBJ-CK802-NEXT: 96e: br32 0x2
+# CHECK-OBJ-CK802-NEXT: 972: addu16 r3, r2, r1
+# CHECK-OBJ-CK802-NEXT: 974: br16 0x976
+
+ addu16 r1, r2, r3
+.L1:
+ jbf .L2
+ addu16 r3, r2, r1
+
+ .rept 600
+ nop
+ .endr
+
+
+ addu16 r1, r2, r3
+.L2:
+ jbt .L1
+ jbr .L1
+ addu16 r3, r2, r1
+ jbr .L3
+.L3:
diff --git a/llvm/test/MC/CSKY/branch-relax-803.s b/llvm/test/MC/CSKY/branch-relax-803.s
new file mode 100644
index 0000000000000..6aacbe20ad143
--- /dev/null
+++ b/llvm/test/MC/CSKY/branch-relax-803.s
@@ -0,0 +1,35 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mcpu=ck803 < %s \
+# RUN: | llvm-objdump --mattr=+2e3 --no-show-raw-insn -M no-aliases -d -r - \
+# RUN: | FileCheck -check-prefixes=CHECK-OBJ-CK803 %s
+
+# CHECK-OBJ-CK803: 0: addu16 r1, r2, r3
+# CHECK-OBJ-CK803-NEXT: 2: bt16 0x8
+# CHECK-OBJ-CK803-NEXT: 4: jmpi32 0x3a9a0 <$d.0>
+# CHECK-OBJ-CK803-NEXT: 8: bsr32 0x3a990 <.text+0x3a990>
+# CHECK-OBJ-CK803-NEXT: c: addu16 r3, r2, r1
+# CHECK-OBJ-CK803: 3a98e: addu16 r1, r2, r3
+# CHECK-OBJ-CK803-NEXT: 3a990: bf16 0x3a996 <.text+0x3a996>
+# CHECK-OBJ-CK803-NEXT: 3a992: jmpi32 0x3a9a4 <$d.0+0x4>
+# CHECK-OBJ-CK803-NEXT: 3a996: jmpi32 0x3a9a4 <$d.0+0x4>
+# CHECK-OBJ-CK803-NEXT: 3a99a: addu16 r3, r2, r1
+# CHECK-OBJ-CK803-NEXT: 3a99c: br16 0x3a99e <.text+0x3a99e>
+
+
+ addu16 r1, r2, r3
+.L1:
+ jbf .L2
+ jbsr .L2
+ addu16 r3, r2, r1
+
+ .rept 60000
+ nop
+ .endr
+
+
+ addu16 r1, r2, r3
+.L2:
+ jbt .L1
+ jbr .L1
+ addu16 r3, r2, r1
+ jbr .L3
+.L3:
diff --git a/llvm/test/MC/CSKY/bsr.s b/llvm/test/MC/CSKY/bsr.s
new file mode 100644
index 0000000000000..f4c79ec6d316a
--- /dev/null
+++ b/llvm/test/MC/CSKY/bsr.s
@@ -0,0 +1,54 @@
+# RUN: llvm-mc -filetype=obj -triple=csky < %s \
+# RUN: | llvm-objdump --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+.data
+sec:
+ .long 0x77
+.text
+tstart:
+ bsr lnk
+ bsr lnk - 4
+ bsr lnk + 4
+ .short 0x1C00
+ bsr sec
+ bsr sec - 4
+ bsr sec + 4
+
+.L1:
+ bsr .L1
+.L2:
+ bsr .L2 - 1024
+.L3:
+ bsr .L3 + 1022
+
+.L4:
+ bsr .L4 - 1026
+.L5:
+ bsr .L5 + 1024
+
+.L6:
+ bsr .L6 - 64*1024*1024
+.L7:
+ bsr .L7 + 64*1024*1024 - 2
+
+
+# CHECK: 0: bsr32 0x0
+# CHECK: 00000000: R_CKCORE_PCREL_IMM26_2 lnk
+# CHECK: 4: bsr32 0x4
+# CHECK: 00000004: R_CKCORE_PCREL_IMM26_2 lnk-0x4
+# CHECK: 8: bsr32 0x8
+# CHECK: 00000008: R_CKCORE_PCREL_IMM26_2 lnk+0x4
+
+# CHECK: e: bsr32 0xe
+# CHECK: 0000000e: R_CKCORE_PCREL_IMM26_2 .data
+# CHECK: 12: bsr32 0x12
+# CHECK: 00000012: R_CKCORE_PCREL_IMM26_2 .data-0x4
+# CHECK: 16: bsr32 0x16
+# CHECK: 00000016: R_CKCORE_PCREL_IMM26_2 .data+0x4
+# CHECK: 1a: bsr32 0x1a
+# CHECK: 1e: bsr32 0xfffffc1e
+# CHECK: 22: bsr32 0x420
+# CHECK: 26: bsr32 0xfffffc24
+# CHECK: 2a: bsr32 0x42a
+# CHECK: 2e: bsr32 0xfc00002e
+# CHECK: 32: bsr32 0x4000030
\ No newline at end of file
diff --git a/llvm/test/MC/CSKY/jmpi.s b/llvm/test/MC/CSKY/jmpi.s
new file mode 100644
index 0000000000000..a02aaac7b5c8a
--- /dev/null
+++ b/llvm/test/MC/CSKY/jmpi.s
@@ -0,0 +1,20 @@
+# RUN: llvm-mc -filetype=obj -triple=csky < %s \
+# RUN: | llvm-objdump --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+
+.text
+
+LABEL:
+ bkpt
+ jmpi LABEL
+ bkpt
+
+
+# CHECK: 0: bkpt
+# CHECK-NEXT: 2: br32 0x0
+# CHECK-NEXT: 6: bkpt
+
+
+# CHECK: 8: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000008: R_CKCORE_ADDR32 .text
+
diff --git a/llvm/test/MC/CSKY/jsri.s b/llvm/test/MC/CSKY/jsri.s
new file mode 100644
index 0000000000000..8342f89f61d9c
--- /dev/null
+++ b/llvm/test/MC/CSKY/jsri.s
@@ -0,0 +1,73 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+2e3 < %s \
+# RUN: | llvm-objdump --mattr=+2e3 --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+
+.data
+sec:
+ .long 0x77
+.text
+tstart:
+ jsri lnk
+ jsri lnk - 4
+ jsri lnk + 4
+ .short 0x1C00
+ jsri sec
+ jsri sec - 4
+ jsri sec + 4
+
+.J1:
+ jsri .J1
+.J2:
+ jsri .J2 - 0x1000
+.J3:
+ jsri .J3 + 0x1000
+
+ jsri 0x01020304
+ jsri 0xFFFFFFFE
+
+
+# CHECK: 0: jsri32 0x30 <$d.4>
+# CHECK-NEXT: 4: jsri32 0x34 <$d.4+0x4>
+# CHECK-NEXT: 8: jsri32 0x38 <$d.4+0x8>
+
+# CHECK: c: 00 1c .short 0x1c00
+
+# CHECK: e: jsri32 0x3c <$d.4+0xc>
+# CHECK-NEXT: 12: jsri32 0x40 <$d.4+0x10>
+# CHECK-NEXT: 16: jsri32 0x44 <$d.4+0x14>
+
+
+
+# CHECK: <.J1>:
+# CHECK-NEXT: 1a: bsr32 0x1a
+
+# CHECK: <.J2>:
+# CHECK-NEXT: 1e: bsr32 0xfffff01e <$d.4+0xffffffffffffefee>
+
+# CHECK: <.J3>:
+# CHECK-NEXT: 22: bsr32 0x1022 <$d.4+0xff2>
+# CHECK-NEXT: 26: jsri32 0x54 <$d.4+0x24>
+# CHECK-NEXT: 2a: jsri32 0x58 <$d.4+0x28>
+# CHECK-NEXT: 2e: bkpt
+
+
+# CHECK: 30: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 00000030: R_CKCORE_ADDR32 lnk
+# CHECK-NEXT: 34: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 00000034: R_CKCORE_ADDR32 lnk-0x4
+# CHECK-NEXT: 38: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 00000038: R_CKCORE_ADDR32 lnk+0x4
+# CHECK-NEXT: 3c: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 0000003c: R_CKCORE_ADDR32 .data
+# CHECK-NEXT: 40: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 00000040: R_CKCORE_ADDR32 .data-0x4
+# CHECK-NEXT: 44: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 00000044: R_CKCORE_ADDR32 .data+0x4
+# CHECK-NEXT: 48: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 00000048: R_CKCORE_ADDR32 .text+0x1a
+# CHECK-NEXT: 4c: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 0000004c: R_CKCORE_ADDR32 .text-0xfe2
+# CHECK-NEXT: 50: 00 00 00 00 .word 0x0
+# CHECK-NEXT: 00000050: R_CKCORE_ADDR32 .text+0x1022
+# CHECK-NEXT: 54: 04 03 02 01 .word 0x01020304
+# CHECK-NEXT: 58: fe ff ff ff .word 0xfffffffe
diff --git a/llvm/test/MC/CSKY/lrs.s b/llvm/test/MC/CSKY/lrs.s
new file mode 100644
index 0000000000000..f0eb66bd388f5
--- /dev/null
+++ b/llvm/test/MC/CSKY/lrs.s
@@ -0,0 +1,57 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+2e3 < %s \
+# RUN: | llvm-objdump --mattr=+2e3 --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+
+.data
+sec:
+ .long 0x77
+.text
+tstart:
+ lrs32.b r0,[lnk]
+ lrs32.b r0,[lnk - 4]
+ lrs32.b r0,[lnk + 4]
+ .short 0x1C00
+ lrs32.h r0,[sec]
+ lrs32.h r0,[sec - 4]
+ lrs32.h r0,[sec + 4]
+ lrs32.b r0,[0]
+ lrs32.b r0,[0xFFFF]
+ lrs32.b r31,[0]
+.L1:
+ lrs32.w r31,[.L1]
+.L2:
+ lrs32.w r0, [.L2]
+.L3:
+ lrs32.w r0, [.L3 - 64*1024]
+.L4:
+ lrs32.w r0, [.L4 + 64*1024 - 2]
+
+# CHECK: 0: lrs32.b r0, [0]
+# CHECK-NEXT: 00000000: R_CKCORE_DOFFSET_IMM18 lnk
+# CHECK-NEXT: 4: lrs32.b r0, [0]
+# CHECK-NEXT: 00000004: R_CKCORE_DOFFSET_IMM18 lnk-0x4
+# CHECK-NEXT: 8: lrs32.b r0, [0]
+# CHECK-NEXT: 00000008: R_CKCORE_DOFFSET_IMM18 lnk+0x4
+
+# CHECK: c: 00 1c .short 0x1c00
+
+# CHECK: e: lrs32.h r0, [0]
+# CHECK-NEXT: 0000000e: R_CKCORE_DOFFSET_IMM18_2 .data
+# CHECK-NEXT: 12: lrs32.h r0, [0]
+# CHECK-NEXT: 00000012: R_CKCORE_DOFFSET_IMM18_2 .data-0x4
+# CHECK-NEXT: 16: lrs32.h r0, [0]
+# CHECK-NEXT: 00000016: R_CKCORE_DOFFSET_IMM18_2 .data+0x4
+# CHECK-NEXT: 1a: lrs32.b r0, [0]
+# CHECK-NEXT: 0000001a: R_CKCORE_DOFFSET_IMM18 *ABS*
+# CHECK-NEXT: 1e: lrs32.b r0, [0]
+# CHECK-NEXT: 0000001e: R_CKCORE_DOFFSET_IMM18 *ABS*+0xffff
+# CHECK-NEXT: 22: lrs32.b r31, [0]
+# CHECK-NEXT: 00000022: R_CKCORE_DOFFSET_IMM18 *ABS*
+# CHECK-NEXT: 26: lrs32.w r31, [0]
+# CHECK-NEXT: 00000026: R_CKCORE_DOFFSET_IMM18_4 .text+0x26
+# CHECK-NEXT: 2a: lrs32.w r0, [0]
+# CHECK-NEXT: 0000002a: R_CKCORE_DOFFSET_IMM18_4 .text+0x2a
+# CHECK-NEXT: 2e: lrs32.w r0, [0]
+# CHECK-NEXT: 0000002e: R_CKCORE_DOFFSET_IMM18_4 .text-0xffd2
+# CHECK-NEXT: 32: lrs32.w r0, [0]
+# CHECK-NEXT: 00000032: R_CKCORE_DOFFSET_IMM18_4 .text+0x10030
diff --git a/llvm/test/MC/CSKY/lrw.s b/llvm/test/MC/CSKY/lrw.s
new file mode 100644
index 0000000000000..69eea7e128c3d
--- /dev/null
+++ b/llvm/test/MC/CSKY/lrw.s
@@ -0,0 +1,73 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+e2 < %s \
+# RUN: | llvm-objdump --mattr=+e2 --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+
+.data
+sec:
+ .long 0x77
+.text
+tstart:
+ lrw r0,lnk
+ lrw r0,lnk - 4
+ lrw r0,lnk + 4
+ .short 0x1C00
+ lrw r0,sec
+ lrw r0,sec - 4
+ lrw r0,sec + 4
+ lrw r0,0
+ lrw r0,0xFFFF
+ lrw r31,0
+.L1:
+ lrw r31,.L1
+.L2:
+ lrw r0, .L2
+.L3:
+ lrw r0, .L3 - 64*1024
+.L4:
+ lrw r0, .L4 + 64*1024 - 2
+
+ lrw r0,0x01020304
+ lrw r0,0xFFFFFFFE
+
+# CHECK: 0: lrw16 r0, 0x28 <$d.4>
+# CHECK-NEXT: 2: lrw16 r0, 0x2c <$d.4+0x4>
+# CHECK-NEXT: 4: lrw16 r0, 0x30 <$d.4+0x8>
+
+# CHECK: 6: 00 1c .short 0x1c00
+
+# CHECK: 8: lrw16 r0, 0x34 <$d.4+0xc>
+# CHECK-NEXT: a: lrw16 r0, 0x38 <$d.4+0x10>
+# CHECK-NEXT: c: lrw16 r0, 0x3c <$d.4+0x14>
+# CHECK-NEXT: e: movi16 r0, 0
+# CHECK-NEXT: 10: movi32 r0, 65535
+# CHECK-NEXT: 14: movi32 r31, 0
+# CHECK-NEXT: 18: lrw32 r31, 0x40 <$d.4+0x18>
+# CHECK-NEXT: 1c: lrw16 r0, 0x44 <$d.4+0x1c>
+# CHECK-NEXT: 1e: lrw16 r0, 0x48 <$d.4+0x20>
+# CHECK-NEXT: 20: lrw16 r0, 0x4c <$d.4+0x24>
+# CHECK-NEXT: 22: lrw16 r0, 0x50 <$d.4+0x28>
+# CHECK-NEXT: 24: lrw16 r0, 0x54 <$d.4+0x2c>
+
+# CHECK: 28: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000028: R_CKCORE_ADDR32 lnk
+# CHECK-NEXT: 2c: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 0000002c: R_CKCORE_ADDR32 lnk-0x4
+# CHECK-NEXT: 30: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000030: R_CKCORE_ADDR32 lnk+0x4
+# CHECK-NEXT: 34: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000034: R_CKCORE_ADDR32 .data
+# CHECK-NEXT: 38: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000038: R_CKCORE_ADDR32 .data-0x4
+# CHECK-NEXT: 3c: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 0000003c: R_CKCORE_ADDR32 .data+0x4
+# CHECK-NEXT: 40: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000040: R_CKCORE_ADDR32 .text+0x18
+# CHECK-NEXT: 44: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000044: R_CKCORE_ADDR32 .text+0x1c
+# CHECK-NEXT: 48: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000048: R_CKCORE_ADDR32 .text-0xffe2
+# CHECK-NEXT: 4c: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 0000004c: R_CKCORE_ADDR32 .text+0x1001e
+# CHECK-NEXT: 50: 04 03 02 01 .word 0x01020304
+# CHECK-NEXT: 54: fe ff ff ff .word 0xfffffffe
+
diff --git a/llvm/test/MC/CSKY/tls_gd.s b/llvm/test/MC/CSKY/tls_gd.s
new file mode 100644
index 0000000000000..3e1cc06238391
--- /dev/null
+++ b/llvm/test/MC/CSKY/tls_gd.s
@@ -0,0 +1,22 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+2e3 < %s \
+# RUN: | llvm-objdump --mattr=+2e3 --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+.LTLS0:
+ lrw16 r0, xxx at TLSGD32
+ grs32 r2, .LTLS0
+ addu16 r0, r0, r2
+ lrw16 r3, __tls_get_addr at PLT
+ ldr32.w r3, (rgb, r3 << 0)
+ jsr16 r3
+
+# CHECK: 0: lrw16 r0, 0x10 <$d.0>
+# CHECK-NEXT: 2: grs32 r2, 0x0
+# CHECK-NEXT: 6: addu16 r0, r0, r2
+# CHECK-NEXT: 8: lrw16 r3, 0x14 <$d.0+0x4>
+# CHECK-NEXT: a: ldr32.w r3, (r28, r3 << 0)
+# CHECK-NEXT: e: jsr16 r3
+
+# CHECK: 10: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000010: R_CKCORE_TLS_GD32 xxx+0x10
+# CHECK-NEXT: 14: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000014: R_CKCORE_PLT32 __tls_get_addr
diff --git a/llvm/test/MC/CSKY/tls_ie.s b/llvm/test/MC/CSKY/tls_ie.s
new file mode 100644
index 0000000000000..1752dfc9b7f90
--- /dev/null
+++ b/llvm/test/MC/CSKY/tls_ie.s
@@ -0,0 +1,22 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+2e3 < %s \
+# RUN: | llvm-objdump --mattr=+2e3 --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+.LTLS0:
+ lrw16 r3, xxx at GOTTPOFF
+ grs32 r2, .LTLS0
+ addu16 r3, r3, r2
+ ld16.w r3, (r3, 0)
+ lsli32 r2, r31, 0
+ str32.w r0, (r2, r3 << 0)
+
+
+# CHECK: 0: lrw16 r3, 0x14 <$d.0>
+# CHECK-NEXT: 2: grs32 r2, 0x0
+# CHECK-NEXT: 6: addu16 r3, r3, r2
+# CHECK-NEXT: 8: ld16.w r3, (r3, 0x0)
+# CHECK-NEXT: a: lsli32 r2, r31, 0
+# CHECK-NEXT: e: str32.w r0, (r2, r3 << 0)
+# CHECK-NEXT: 12: bkpt
+
+# CHECK: 14: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000014: R_CKCORE_TLS_IE32 xxx+0x14
diff --git a/llvm/test/MC/CSKY/tls_ld.s b/llvm/test/MC/CSKY/tls_ld.s
new file mode 100644
index 0000000000000..c4cbf15dfd81f
--- /dev/null
+++ b/llvm/test/MC/CSKY/tls_ld.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+2e3 < %s \
+# RUN: | llvm-objdump --mattr=+2e3 --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+.LTLS0:
+ lrw16 r0, xxx at TLSLDM32
+ grs32 r2, .LTLS0
+ addu16 r0, r0, r2
+ lrw16 r3, __tls_get_addr at PLT
+ ldr32.w r3, (rgb, r3 << 0)
+ jsr16 r3
+ lrw16 r3, xxx at TLSLDO32
+ str32.w r4, (r0, r3 << 0)
+
+# CHECK: 0: lrw16 r0, 0x18 <$d.0>
+# CHECK-NEXT: 2: grs32 r2, 0x0
+# CHECK-NEXT: 6: addu16 r0, r0, r2
+# CHECK-NEXT: 8: lrw16 r3, 0x1c <$d.0+0x4>
+# CHECK-NEXT: a: ldr32.w r3, (r28, r3 << 0)
+# CHECK-NEXT: e: jsr16 r3
+# CHECK-NEXT: 10: lrw16 r3, 0x20 <$d.0+0x8>
+# CHECK-NEXT: 12: str32.w r4, (r0, r3 << 0)
+# CHECK-NEXT: 16: bkpt
+
+# CHECK: 18: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000018: R_CKCORE_TLS_LDM32 xxx+0x18
+# CHECK-NEXT: 1c: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 0000001c: R_CKCORE_PLT32 __tls_get_addr
+# CHECK-NEXT: 20: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 00000020: R_CKCORE_TLS_LDO32 xxx
diff --git a/llvm/test/MC/CSKY/tls_le.s b/llvm/test/MC/CSKY/tls_le.s
new file mode 100644
index 0000000000000..3206643ef255f
--- /dev/null
+++ b/llvm/test/MC/CSKY/tls_le.s
@@ -0,0 +1,14 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+2e3 < %s \
+# RUN: | llvm-objdump --mattr=+2e3 --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+ lrw16 r3, xxx at TPOFF
+ lsli32 r2, r31, 0
+ str32.w r0, (r2, r3 << 0)
+
+# CHECK: 0: lrw16 r3, 0xc <$d.0>
+# CHECK-NEXT: 2: lsli32 r2, r31, 0
+# CHECK-NEXT: 6: str32.w r0, (r2, r3 << 0)
+# CHECK-NEXT: a: bkpt
+
+# CHECK: c: 00 00 00 00 .word 0x00000000
+# CHECK-NEXT: 0000000c: R_CKCORE_TLS_LE32 xxx
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index c8c512659f4b0..a9ce463c22bb1 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -441,8 +441,13 @@ static bool isArmElf(const ObjectFile *Obj) {
return Elf && Elf->getEMachine() == ELF::EM_ARM;
}
+static bool isCSKYElf(const ObjectFile *Obj) {
+ const auto *Elf = dyn_cast<ELFObjectFileBase>(Obj);
+ return Elf && Elf->getEMachine() == ELF::EM_CSKY;
+}
+
static bool hasMappingSymbols(const ObjectFile *Obj) {
- return isArmElf(Obj) || isAArch64Elf(Obj);
+ return isArmElf(Obj) || isAArch64Elf(Obj) || isCSKYElf(Obj) ;
}
static void printRelocation(formatted_raw_ostream &OS, StringRef FileName,
More information about the llvm-commits
mailing list