xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1e8d8bef9SDimitry Andric //===-- CSKYAsmBackend.cpp - CSKY Assembler Backend -----------------------===//
2e8d8bef9SDimitry Andric //
3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric //
7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric 
9e8d8bef9SDimitry Andric #include "CSKYAsmBackend.h"
10e8d8bef9SDimitry Andric #include "MCTargetDesc/CSKYMCTargetDesc.h"
11fe6060f1SDimitry Andric #include "llvm/ADT/DenseMap.h"
12e8d8bef9SDimitry Andric #include "llvm/MC/MCAssembler.h"
13e8d8bef9SDimitry Andric #include "llvm/MC/MCContext.h"
14e8d8bef9SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h"
15e8d8bef9SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
16e8d8bef9SDimitry Andric #include "llvm/Support/Debug.h"
17e8d8bef9SDimitry Andric 
18e8d8bef9SDimitry Andric #define DEBUG_TYPE "csky-asmbackend"
19e8d8bef9SDimitry Andric 
20e8d8bef9SDimitry Andric using namespace llvm;
21e8d8bef9SDimitry Andric 
22e8d8bef9SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
23e8d8bef9SDimitry Andric CSKYAsmBackend::createObjectTargetWriter() const {
24e8d8bef9SDimitry Andric   return createCSKYELFObjectWriter();
25e8d8bef9SDimitry Andric }
26e8d8bef9SDimitry Andric 
27fe6060f1SDimitry Andric const MCFixupKindInfo &
28fe6060f1SDimitry Andric CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
29fe6060f1SDimitry Andric 
30fe6060f1SDimitry Andric   static llvm::DenseMap<unsigned, MCFixupKindInfo> Infos = {
31fe6060f1SDimitry Andric       {CSKY::Fixups::fixup_csky_addr32, {"fixup_csky_addr32", 0, 32, 0}},
32349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_addr_hi16, {"fixup_csky_addr_hi16", 0, 32, 0}},
33349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_addr_lo16, {"fixup_csky_addr_lo16", 0, 32, 0}},
34fe6060f1SDimitry Andric       {CSKY::Fixups::fixup_csky_pcrel_imm16_scale2,
35fe6060f1SDimitry Andric        {"fixup_csky_pcrel_imm16_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
36fe6060f1SDimitry Andric       {CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4,
37349cc55cSDimitry Andric        {"fixup_csky_pcrel_uimm16_scale4", 0, 32,
38349cc55cSDimitry Andric         MCFixupKindInfo::FKF_IsPCRel |
39349cc55cSDimitry Andric             MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
40349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4,
41349cc55cSDimitry Andric        {"fixup_csky_pcrel_uimm8_scale4", 0, 32,
42349cc55cSDimitry Andric         MCFixupKindInfo::FKF_IsPCRel |
43349cc55cSDimitry Andric             MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
44fe6060f1SDimitry Andric       {CSKY::Fixups::fixup_csky_pcrel_imm26_scale2,
45fe6060f1SDimitry Andric        {"fixup_csky_pcrel_imm26_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
46fe6060f1SDimitry Andric       {CSKY::Fixups::fixup_csky_pcrel_imm18_scale2,
47349cc55cSDimitry Andric        {"fixup_csky_pcrel_imm18_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
48349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_got32, {"fixup_csky_got32", 0, 32, 0}},
49349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_got_imm18_scale4,
50349cc55cSDimitry Andric        {"fixup_csky_got_imm18_scale4", 0, 32, 0}},
51349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_gotoff, {"fixup_csky_gotoff", 0, 32, 0}},
52349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_gotpc,
53349cc55cSDimitry Andric        {"fixup_csky_gotpc", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
54349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_plt32, {"fixup_csky_plt32", 0, 32, 0}},
55349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_plt_imm18_scale4,
56349cc55cSDimitry Andric        {"fixup_csky_plt_imm18_scale4", 0, 32, 0}},
57349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_pcrel_imm10_scale2,
58349cc55cSDimitry Andric        {"fixup_csky_pcrel_imm10_scale2", 0, 16, MCFixupKindInfo::FKF_IsPCRel}},
59349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4,
60349cc55cSDimitry Andric        {"fixup_csky_pcrel_uimm7_scale4", 0, 16,
61349cc55cSDimitry Andric         MCFixupKindInfo::FKF_IsPCRel |
62349cc55cSDimitry Andric             MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
63349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_doffset_imm18,
64349cc55cSDimitry Andric        {"fixup_csky_doffset_imm18", 0, 18, 0}},
65349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_doffset_imm18_scale2,
66349cc55cSDimitry Andric        {"fixup_csky_doffset_imm18_scale2", 0, 18, 0}},
67349cc55cSDimitry Andric       {CSKY::Fixups::fixup_csky_doffset_imm18_scale4,
68349cc55cSDimitry Andric        {"fixup_csky_doffset_imm18_scale4", 0, 18, 0}}};
69349cc55cSDimitry Andric 
70fe6060f1SDimitry Andric   assert(Infos.size() == CSKY::NumTargetFixupKinds &&
71fe6060f1SDimitry Andric          "Not all fixup kinds added to Infos array");
72fe6060f1SDimitry Andric 
73349cc55cSDimitry Andric   if (FirstTargetFixupKind <= Kind && Kind < FirstLiteralRelocationKind) {
74fe6060f1SDimitry Andric     assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
75fe6060f1SDimitry Andric            "Invalid kind!");
76349cc55cSDimitry Andric 
77fe6060f1SDimitry Andric     return Infos[Kind];
78349cc55cSDimitry Andric   } else if (Kind < FirstTargetFixupKind) {
79fe6060f1SDimitry Andric     return MCAsmBackend::getFixupKindInfo(Kind);
80349cc55cSDimitry Andric   } else {
81fe6060f1SDimitry Andric     return MCAsmBackend::getFixupKindInfo(FK_NONE);
82fe6060f1SDimitry Andric   }
83349cc55cSDimitry Andric }
84fe6060f1SDimitry Andric 
85fe6060f1SDimitry Andric static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
86fe6060f1SDimitry Andric                                  MCContext &Ctx) {
87fe6060f1SDimitry Andric   switch (Fixup.getTargetKind()) {
88fe6060f1SDimitry Andric   default:
89fe6060f1SDimitry Andric     llvm_unreachable("Unknown fixup kind!");
9081ad6265SDimitry Andric   case CSKY::fixup_csky_got32:
9181ad6265SDimitry Andric   case CSKY::fixup_csky_got_imm18_scale4:
9281ad6265SDimitry Andric   case CSKY::fixup_csky_gotoff:
9381ad6265SDimitry Andric   case CSKY::fixup_csky_gotpc:
9481ad6265SDimitry Andric   case CSKY::fixup_csky_plt32:
9581ad6265SDimitry Andric   case CSKY::fixup_csky_plt_imm18_scale4:
9681ad6265SDimitry Andric     llvm_unreachable("Relocation should be unconditionally forced\n");
97fe6060f1SDimitry Andric   case FK_Data_1:
98fe6060f1SDimitry Andric   case FK_Data_2:
99fe6060f1SDimitry Andric   case FK_Data_4:
100fe6060f1SDimitry Andric   case FK_Data_8:
101fe6060f1SDimitry Andric     return Value;
102fe6060f1SDimitry Andric   case CSKY::fixup_csky_addr32:
103fe6060f1SDimitry Andric     return Value & 0xffffffff;
104fe6060f1SDimitry Andric   case CSKY::fixup_csky_pcrel_imm16_scale2:
105fe6060f1SDimitry Andric     if (!isIntN(17, Value))
106fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
107fe6060f1SDimitry Andric     if (Value & 0x1)
108fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
109fe6060f1SDimitry Andric 
110fe6060f1SDimitry Andric     return (Value >> 1) & 0xffff;
111fe6060f1SDimitry Andric   case CSKY::fixup_csky_pcrel_uimm16_scale4:
112fe6060f1SDimitry Andric     if (!isUIntN(18, Value))
113fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
114fe6060f1SDimitry Andric     if (Value & 0x3)
115fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
116fe6060f1SDimitry Andric 
117fe6060f1SDimitry Andric     return (Value >> 2) & 0xffff;
118fe6060f1SDimitry Andric   case CSKY::fixup_csky_pcrel_imm26_scale2:
119fe6060f1SDimitry Andric     if (!isIntN(27, Value))
120fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
121fe6060f1SDimitry Andric     if (Value & 0x1)
122fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
123fe6060f1SDimitry Andric 
124fe6060f1SDimitry Andric     return (Value >> 1) & 0x3ffffff;
125fe6060f1SDimitry Andric   case CSKY::fixup_csky_pcrel_imm18_scale2:
126fe6060f1SDimitry Andric     if (!isIntN(19, Value))
127fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
128fe6060f1SDimitry Andric     if (Value & 0x1)
129fe6060f1SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
130fe6060f1SDimitry Andric 
131fe6060f1SDimitry Andric     return (Value >> 1) & 0x3ffff;
13281ad6265SDimitry Andric   case CSKY::fixup_csky_pcrel_uimm8_scale4: {
13381ad6265SDimitry Andric     if (!isUIntN(10, Value))
13481ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
13581ad6265SDimitry Andric     if (Value & 0x3)
13681ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
13781ad6265SDimitry Andric 
13881ad6265SDimitry Andric     unsigned IMM4L = (Value >> 2) & 0xf;
13981ad6265SDimitry Andric     unsigned IMM4H = (Value >> 6) & 0xf;
14081ad6265SDimitry Andric 
14181ad6265SDimitry Andric     Value = (IMM4H << 21) | (IMM4L << 4);
14281ad6265SDimitry Andric     return Value;
14381ad6265SDimitry Andric   }
14481ad6265SDimitry Andric   case CSKY::fixup_csky_pcrel_imm10_scale2:
14581ad6265SDimitry Andric     if (!isIntN(11, Value))
14681ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
14781ad6265SDimitry Andric     if (Value & 0x1)
14881ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
14981ad6265SDimitry Andric 
15081ad6265SDimitry Andric     return (Value >> 1) & 0x3ff;
15181ad6265SDimitry Andric   case CSKY::fixup_csky_pcrel_uimm7_scale4:
152bdd1243dSDimitry Andric     if ((Value >> 2) > 0xfe)
15381ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
15481ad6265SDimitry Andric     if (Value & 0x3)
15581ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
15681ad6265SDimitry Andric 
157bdd1243dSDimitry Andric     if ((Value >> 2) <= 0x7f) {
15881ad6265SDimitry Andric       unsigned IMM5L = (Value >> 2) & 0x1f;
15981ad6265SDimitry Andric       unsigned IMM2H = (Value >> 7) & 0x3;
16081ad6265SDimitry Andric 
16181ad6265SDimitry Andric       Value = (1 << 12) | (IMM2H << 8) | IMM5L;
16281ad6265SDimitry Andric     } else {
163bdd1243dSDimitry Andric       unsigned IMM5L = (~Value >> 2) & 0x1f;
164bdd1243dSDimitry Andric       unsigned IMM2H = (~Value >> 7) & 0x3;
16581ad6265SDimitry Andric 
16681ad6265SDimitry Andric       Value = (IMM2H << 8) | IMM5L;
16781ad6265SDimitry Andric     }
16881ad6265SDimitry Andric 
169bdd1243dSDimitry Andric     return Value;
17081ad6265SDimitry Andric   }
17181ad6265SDimitry Andric }
17281ad6265SDimitry Andric 
173*0fca6ea1SDimitry Andric bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCAssembler &Asm,
174*0fca6ea1SDimitry Andric                                                   const MCFixup &Fixup,
17581ad6265SDimitry Andric                                                   bool Resolved, uint64_t Value,
17681ad6265SDimitry Andric                                                   const MCRelaxableFragment *DF,
17781ad6265SDimitry Andric                                                   const bool WasForced) const {
17881ad6265SDimitry Andric   // Return true if the symbol is actually unresolved.
17981ad6265SDimitry Andric   // Resolved could be always false when shouldForceRelocation return true.
18081ad6265SDimitry Andric   // We use !WasForced to indicate that the symbol is unresolved and not forced
18181ad6265SDimitry Andric   // by shouldForceRelocation.
18281ad6265SDimitry Andric   if (!Resolved && !WasForced)
18381ad6265SDimitry Andric     return true;
18481ad6265SDimitry Andric 
18581ad6265SDimitry Andric   int64_t Offset = int64_t(Value);
18681ad6265SDimitry Andric   switch (Fixup.getTargetKind()) {
18781ad6265SDimitry Andric   default:
18881ad6265SDimitry Andric     return false;
18981ad6265SDimitry Andric   case CSKY::fixup_csky_pcrel_imm10_scale2:
19081ad6265SDimitry Andric     return !isShiftedInt<10, 1>(Offset);
19181ad6265SDimitry Andric   case CSKY::fixup_csky_pcrel_imm16_scale2:
19281ad6265SDimitry Andric     return !isShiftedInt<16, 1>(Offset);
19381ad6265SDimitry Andric   case CSKY::fixup_csky_pcrel_imm26_scale2:
19481ad6265SDimitry Andric     return !isShiftedInt<26, 1>(Offset);
19581ad6265SDimitry Andric   case CSKY::fixup_csky_pcrel_uimm7_scale4:
196bdd1243dSDimitry Andric     return ((Value >> 2) > 0xfe) || (Value & 0x3);
197fe6060f1SDimitry Andric   }
198fe6060f1SDimitry Andric }
199e8d8bef9SDimitry Andric 
200e8d8bef9SDimitry Andric void CSKYAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
201e8d8bef9SDimitry Andric                                 const MCValue &Target,
202e8d8bef9SDimitry Andric                                 MutableArrayRef<char> Data, uint64_t Value,
203e8d8bef9SDimitry Andric                                 bool IsResolved,
204e8d8bef9SDimitry Andric                                 const MCSubtargetInfo *STI) const {
205fe6060f1SDimitry Andric   MCFixupKind Kind = Fixup.getKind();
206fe6060f1SDimitry Andric   if (Kind >= FirstLiteralRelocationKind)
207e8d8bef9SDimitry Andric     return;
208fe6060f1SDimitry Andric   MCContext &Ctx = Asm.getContext();
209fe6060f1SDimitry Andric   MCFixupKindInfo Info = getFixupKindInfo(Kind);
210fe6060f1SDimitry Andric   if (!Value)
211fe6060f1SDimitry Andric     return; // Doesn't change encoding.
212fe6060f1SDimitry Andric   // Apply any target-specific value adjustments.
213fe6060f1SDimitry Andric   Value = adjustFixupValue(Fixup, Value, Ctx);
214fe6060f1SDimitry Andric 
215fe6060f1SDimitry Andric   // Shift the value into position.
216fe6060f1SDimitry Andric   Value <<= Info.TargetOffset;
217fe6060f1SDimitry Andric 
218fe6060f1SDimitry Andric   unsigned Offset = Fixup.getOffset();
219fe6060f1SDimitry Andric   unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8;
220fe6060f1SDimitry Andric 
221fe6060f1SDimitry Andric   assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
222fe6060f1SDimitry Andric 
223fe6060f1SDimitry Andric   // For each byte of the fragment that the fixup touches, mask in the
224fe6060f1SDimitry Andric   // bits from the fixup value.
2255f757f3fSDimitry Andric   bool IsLittleEndian = (Endian == llvm::endianness::little);
22681ad6265SDimitry Andric   bool IsInstFixup = (Kind >= FirstTargetFixupKind);
227fe6060f1SDimitry Andric 
22881ad6265SDimitry Andric   if (IsLittleEndian && IsInstFixup && (NumBytes == 4)) {
229fe6060f1SDimitry Andric     Data[Offset + 0] |= uint8_t((Value >> 16) & 0xff);
230fe6060f1SDimitry Andric     Data[Offset + 1] |= uint8_t((Value >> 24) & 0xff);
231fe6060f1SDimitry Andric     Data[Offset + 2] |= uint8_t(Value & 0xff);
232fe6060f1SDimitry Andric     Data[Offset + 3] |= uint8_t((Value >> 8) & 0xff);
233fe6060f1SDimitry Andric   } else {
234fe6060f1SDimitry Andric     for (unsigned I = 0; I != NumBytes; I++) {
235fe6060f1SDimitry Andric       unsigned Idx = IsLittleEndian ? I : (NumBytes - 1 - I);
236fe6060f1SDimitry Andric       Data[Offset + Idx] |= uint8_t((Value >> (I * 8)) & 0xff);
237fe6060f1SDimitry Andric     }
238fe6060f1SDimitry Andric   }
239e8d8bef9SDimitry Andric }
240e8d8bef9SDimitry Andric 
24181ad6265SDimitry Andric bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst,
24281ad6265SDimitry Andric                                        const MCSubtargetInfo &STI) const {
24381ad6265SDimitry Andric   switch (Inst.getOpcode()) {
24481ad6265SDimitry Andric   default:
24581ad6265SDimitry Andric     return false;
24681ad6265SDimitry Andric   case CSKY::JBR32:
24781ad6265SDimitry Andric   case CSKY::JBT32:
24881ad6265SDimitry Andric   case CSKY::JBF32:
24981ad6265SDimitry Andric   case CSKY::JBSR32:
25006c3fb27SDimitry Andric     if (!STI.hasFeature(CSKY::Has2E3))
25181ad6265SDimitry Andric       return false;
25281ad6265SDimitry Andric     return true;
25381ad6265SDimitry Andric   case CSKY::JBR16:
25481ad6265SDimitry Andric   case CSKY::JBT16:
25581ad6265SDimitry Andric   case CSKY::JBF16:
25681ad6265SDimitry Andric   case CSKY::LRW16:
25781ad6265SDimitry Andric   case CSKY::BR16:
25881ad6265SDimitry Andric     return true;
25981ad6265SDimitry Andric   }
26081ad6265SDimitry Andric }
26181ad6265SDimitry Andric 
26281ad6265SDimitry Andric bool CSKYAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
26381ad6265SDimitry Andric                                            const MCFixup &Fixup,
2645f757f3fSDimitry Andric                                            const MCValue &Target,
2655f757f3fSDimitry Andric                                            const MCSubtargetInfo * /*STI*/) {
26681ad6265SDimitry Andric   if (Fixup.getKind() >= FirstLiteralRelocationKind)
26781ad6265SDimitry Andric     return true;
26881ad6265SDimitry Andric   switch (Fixup.getTargetKind()) {
26981ad6265SDimitry Andric   default:
27081ad6265SDimitry Andric     break;
27181ad6265SDimitry Andric   case CSKY::fixup_csky_got32:
27281ad6265SDimitry Andric   case CSKY::fixup_csky_got_imm18_scale4:
27381ad6265SDimitry Andric   case CSKY::fixup_csky_gotoff:
27481ad6265SDimitry Andric   case CSKY::fixup_csky_gotpc:
27581ad6265SDimitry Andric   case CSKY::fixup_csky_plt32:
27681ad6265SDimitry Andric   case CSKY::fixup_csky_plt_imm18_scale4:
27781ad6265SDimitry Andric   case CSKY::fixup_csky_doffset_imm18:
27881ad6265SDimitry Andric   case CSKY::fixup_csky_doffset_imm18_scale2:
27981ad6265SDimitry Andric   case CSKY::fixup_csky_doffset_imm18_scale4:
28081ad6265SDimitry Andric     return true;
28181ad6265SDimitry Andric   }
28281ad6265SDimitry Andric 
28381ad6265SDimitry Andric   return false;
28481ad6265SDimitry Andric }
28581ad6265SDimitry Andric 
286*0fca6ea1SDimitry Andric bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
287*0fca6ea1SDimitry Andric                                           uint64_t Value) const {
288e8d8bef9SDimitry Andric   return false;
289e8d8bef9SDimitry Andric }
290e8d8bef9SDimitry Andric 
291e8d8bef9SDimitry Andric void CSKYAsmBackend::relaxInstruction(MCInst &Inst,
292e8d8bef9SDimitry Andric                                       const MCSubtargetInfo &STI) const {
29381ad6265SDimitry Andric   MCInst Res;
29481ad6265SDimitry Andric 
29581ad6265SDimitry Andric   switch (Inst.getOpcode()) {
29681ad6265SDimitry Andric   default:
29781ad6265SDimitry Andric     LLVM_DEBUG(Inst.dump());
29881ad6265SDimitry Andric     llvm_unreachable("Opcode not expected!");
29981ad6265SDimitry Andric   case CSKY::LRW16:
30081ad6265SDimitry Andric     Res.setOpcode(CSKY::LRW32);
30181ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(0));
30281ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(1));
30381ad6265SDimitry Andric     break;
30481ad6265SDimitry Andric   case CSKY::BR16:
30581ad6265SDimitry Andric     Res.setOpcode(CSKY::BR32);
30681ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(0));
30781ad6265SDimitry Andric     break;
30881ad6265SDimitry Andric   case CSKY::JBSR32:
30981ad6265SDimitry Andric     Res.setOpcode(CSKY::JSRI32);
31081ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(1));
31181ad6265SDimitry Andric     break;
31281ad6265SDimitry Andric   case CSKY::JBR32:
31381ad6265SDimitry Andric     Res.setOpcode(CSKY::JMPI32);
31481ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(1));
31581ad6265SDimitry Andric     break;
31681ad6265SDimitry Andric   case CSKY::JBT32:
31781ad6265SDimitry Andric   case CSKY::JBF32:
31881ad6265SDimitry Andric     Res.setOpcode(Inst.getOpcode() == CSKY::JBT32 ? CSKY::JBT_E : CSKY::JBF_E);
31981ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(0));
32081ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(1));
32181ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(2));
32281ad6265SDimitry Andric     break;
32381ad6265SDimitry Andric   case CSKY::JBR16:
32481ad6265SDimitry Andric     Res.setOpcode(CSKY::JBR32);
32581ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(0));
32681ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(1));
32781ad6265SDimitry Andric     break;
32881ad6265SDimitry Andric   case CSKY::JBT16:
32981ad6265SDimitry Andric   case CSKY::JBF16:
33081ad6265SDimitry Andric     // ck801
33181ad6265SDimitry Andric     unsigned opcode;
33206c3fb27SDimitry Andric     if (STI.hasFeature(CSKY::HasE2))
33381ad6265SDimitry Andric       opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT32 : CSKY::JBF32;
33481ad6265SDimitry Andric     else
33581ad6265SDimitry Andric       opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT_E : CSKY::JBF_E;
33681ad6265SDimitry Andric 
33781ad6265SDimitry Andric     Res.setOpcode(opcode);
33881ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(0));
33981ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(1));
34081ad6265SDimitry Andric     Res.addOperand(Inst.getOperand(2));
34181ad6265SDimitry Andric     break;
34281ad6265SDimitry Andric   }
34381ad6265SDimitry Andric   Inst = std::move(Res);
344e8d8bef9SDimitry Andric }
345e8d8bef9SDimitry Andric 
346349cc55cSDimitry Andric bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
347349cc55cSDimitry Andric                                   const MCSubtargetInfo *STI) const {
34881ad6265SDimitry Andric   OS.write_zeros(Count);
349e8d8bef9SDimitry Andric   return true;
350e8d8bef9SDimitry Andric }
351e8d8bef9SDimitry Andric 
352e8d8bef9SDimitry Andric MCAsmBackend *llvm::createCSKYAsmBackend(const Target &T,
353e8d8bef9SDimitry Andric                                          const MCSubtargetInfo &STI,
354e8d8bef9SDimitry Andric                                          const MCRegisterInfo &MRI,
355e8d8bef9SDimitry Andric                                          const MCTargetOptions &Options) {
356e8d8bef9SDimitry Andric   return new CSKYAsmBackend(STI, Options);
357e8d8bef9SDimitry Andric }
358