1ec17c4f0SZi Xuan Wu //===-- CSKYAsmBackend.cpp - CSKY Assembler Backend -----------------------===//
2ec17c4f0SZi Xuan Wu //
3ec17c4f0SZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ec17c4f0SZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information.
5ec17c4f0SZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec17c4f0SZi Xuan Wu //
7ec17c4f0SZi Xuan Wu //===----------------------------------------------------------------------===//
8ec17c4f0SZi Xuan Wu 
9ec17c4f0SZi Xuan Wu #include "CSKYAsmBackend.h"
10ec17c4f0SZi Xuan Wu #include "MCTargetDesc/CSKYMCTargetDesc.h"
114bb60c28SZi Xuan Wu #include "llvm/ADT/DenseMap.h"
12ec17c4f0SZi Xuan Wu #include "llvm/MC/MCAsmLayout.h"
13ec17c4f0SZi Xuan Wu #include "llvm/MC/MCAssembler.h"
14ec17c4f0SZi Xuan Wu #include "llvm/MC/MCContext.h"
15ec17c4f0SZi Xuan Wu #include "llvm/MC/MCFixupKindInfo.h"
16ec17c4f0SZi Xuan Wu #include "llvm/MC/MCObjectWriter.h"
17ec17c4f0SZi Xuan Wu #include "llvm/Support/Debug.h"
18ec17c4f0SZi Xuan Wu 
19ec17c4f0SZi Xuan Wu #define DEBUG_TYPE "csky-asmbackend"
20ec17c4f0SZi Xuan Wu 
21ec17c4f0SZi Xuan Wu using namespace llvm;
22ec17c4f0SZi Xuan Wu 
23ec17c4f0SZi Xuan Wu std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const24ec17c4f0SZi Xuan Wu CSKYAsmBackend::createObjectTargetWriter() const {
25ec17c4f0SZi Xuan Wu   return createCSKYELFObjectWriter();
26ec17c4f0SZi Xuan Wu }
27ec17c4f0SZi Xuan Wu 
284bb60c28SZi Xuan Wu const MCFixupKindInfo &
getFixupKindInfo(MCFixupKind Kind) const294bb60c28SZi Xuan Wu CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
304bb60c28SZi Xuan Wu 
314bb60c28SZi Xuan Wu   static llvm::DenseMap<unsigned, MCFixupKindInfo> Infos = {
324bb60c28SZi Xuan Wu       {CSKY::Fixups::fixup_csky_addr32, {"fixup_csky_addr32", 0, 32, 0}},
33de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_addr_hi16, {"fixup_csky_addr_hi16", 0, 32, 0}},
34de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_addr_lo16, {"fixup_csky_addr_lo16", 0, 32, 0}},
354bb60c28SZi Xuan Wu       {CSKY::Fixups::fixup_csky_pcrel_imm16_scale2,
364bb60c28SZi Xuan Wu        {"fixup_csky_pcrel_imm16_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
374bb60c28SZi Xuan Wu       {CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4,
38de10a02fSZi Xuan Wu        {"fixup_csky_pcrel_uimm16_scale4", 0, 32,
39de10a02fSZi Xuan Wu         MCFixupKindInfo::FKF_IsPCRel |
40de10a02fSZi Xuan Wu             MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
41de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4,
42de10a02fSZi Xuan Wu        {"fixup_csky_pcrel_uimm8_scale4", 0, 32,
43de10a02fSZi Xuan Wu         MCFixupKindInfo::FKF_IsPCRel |
44de10a02fSZi Xuan Wu             MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
454bb60c28SZi Xuan Wu       {CSKY::Fixups::fixup_csky_pcrel_imm26_scale2,
464bb60c28SZi Xuan Wu        {"fixup_csky_pcrel_imm26_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
474bb60c28SZi Xuan Wu       {CSKY::Fixups::fixup_csky_pcrel_imm18_scale2,
48de10a02fSZi Xuan Wu        {"fixup_csky_pcrel_imm18_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
49de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_got32, {"fixup_csky_got32", 0, 32, 0}},
50de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_got_imm18_scale4,
51de10a02fSZi Xuan Wu        {"fixup_csky_got_imm18_scale4", 0, 32, 0}},
52de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_gotoff, {"fixup_csky_gotoff", 0, 32, 0}},
53de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_gotpc,
54de10a02fSZi Xuan Wu        {"fixup_csky_gotpc", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
55de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_plt32, {"fixup_csky_plt32", 0, 32, 0}},
56de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_plt_imm18_scale4,
57de10a02fSZi Xuan Wu        {"fixup_csky_plt_imm18_scale4", 0, 32, 0}},
58de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_pcrel_imm10_scale2,
59de10a02fSZi Xuan Wu        {"fixup_csky_pcrel_imm10_scale2", 0, 16, MCFixupKindInfo::FKF_IsPCRel}},
60de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4,
61de10a02fSZi Xuan Wu        {"fixup_csky_pcrel_uimm7_scale4", 0, 16,
62de10a02fSZi Xuan Wu         MCFixupKindInfo::FKF_IsPCRel |
63de10a02fSZi Xuan Wu             MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
64de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_doffset_imm18,
65de10a02fSZi Xuan Wu        {"fixup_csky_doffset_imm18", 0, 18, 0}},
66de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_doffset_imm18_scale2,
67de10a02fSZi Xuan Wu        {"fixup_csky_doffset_imm18_scale2", 0, 18, 0}},
68de10a02fSZi Xuan Wu       {CSKY::Fixups::fixup_csky_doffset_imm18_scale4,
69de10a02fSZi Xuan Wu        {"fixup_csky_doffset_imm18_scale4", 0, 18, 0}}};
70de10a02fSZi Xuan Wu 
714bb60c28SZi Xuan Wu   assert(Infos.size() == CSKY::NumTargetFixupKinds &&
724bb60c28SZi Xuan Wu          "Not all fixup kinds added to Infos array");
734bb60c28SZi Xuan Wu 
74de10a02fSZi Xuan Wu   if (FirstTargetFixupKind <= Kind && Kind < FirstLiteralRelocationKind) {
754bb60c28SZi Xuan Wu     assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
764bb60c28SZi Xuan Wu            "Invalid kind!");
77de10a02fSZi Xuan Wu 
784bb60c28SZi Xuan Wu     return Infos[Kind];
79de10a02fSZi Xuan Wu   } else if (Kind < FirstTargetFixupKind) {
804bb60c28SZi Xuan Wu     return MCAsmBackend::getFixupKindInfo(Kind);
81de10a02fSZi Xuan Wu   } else {
824bb60c28SZi Xuan Wu     return MCAsmBackend::getFixupKindInfo(FK_NONE);
834bb60c28SZi Xuan Wu   }
84de10a02fSZi Xuan Wu }
854bb60c28SZi Xuan Wu 
adjustFixupValue(const MCFixup & Fixup,uint64_t Value,MCContext & Ctx)864bb60c28SZi Xuan Wu static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
874bb60c28SZi Xuan Wu                                  MCContext &Ctx) {
884bb60c28SZi Xuan Wu   switch (Fixup.getTargetKind()) {
894bb60c28SZi Xuan Wu   default:
904bb60c28SZi Xuan Wu     llvm_unreachable("Unknown fixup kind!");
91582836faSZi Xuan Wu   case CSKY::fixup_csky_got32:
92582836faSZi Xuan Wu   case CSKY::fixup_csky_got_imm18_scale4:
93582836faSZi Xuan Wu   case CSKY::fixup_csky_gotoff:
94582836faSZi Xuan Wu   case CSKY::fixup_csky_gotpc:
95582836faSZi Xuan Wu   case CSKY::fixup_csky_plt32:
96582836faSZi Xuan Wu   case CSKY::fixup_csky_plt_imm18_scale4:
97582836faSZi Xuan Wu     llvm_unreachable("Relocation should be unconditionally forced\n");
984bb60c28SZi Xuan Wu   case FK_Data_1:
994bb60c28SZi Xuan Wu   case FK_Data_2:
1004bb60c28SZi Xuan Wu   case FK_Data_4:
1014bb60c28SZi Xuan Wu   case FK_Data_8:
1024bb60c28SZi Xuan Wu     return Value;
1034bb60c28SZi Xuan Wu   case CSKY::fixup_csky_addr32:
1044bb60c28SZi Xuan Wu     return Value & 0xffffffff;
1054bb60c28SZi Xuan Wu   case CSKY::fixup_csky_pcrel_imm16_scale2:
1064bb60c28SZi Xuan Wu     if (!isIntN(17, Value))
1074bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
1084bb60c28SZi Xuan Wu     if (Value & 0x1)
1094bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
1104bb60c28SZi Xuan Wu 
1114bb60c28SZi Xuan Wu     return (Value >> 1) & 0xffff;
1124bb60c28SZi Xuan Wu   case CSKY::fixup_csky_pcrel_uimm16_scale4:
1134bb60c28SZi Xuan Wu     if (!isUIntN(18, Value))
1144bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
1154bb60c28SZi Xuan Wu     if (Value & 0x3)
1164bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
1174bb60c28SZi Xuan Wu 
1184bb60c28SZi Xuan Wu     return (Value >> 2) & 0xffff;
1194bb60c28SZi Xuan Wu   case CSKY::fixup_csky_pcrel_imm26_scale2:
1204bb60c28SZi Xuan Wu     if (!isIntN(27, Value))
1214bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
1224bb60c28SZi Xuan Wu     if (Value & 0x1)
1234bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
1244bb60c28SZi Xuan Wu 
1254bb60c28SZi Xuan Wu     return (Value >> 1) & 0x3ffffff;
1264bb60c28SZi Xuan Wu   case CSKY::fixup_csky_pcrel_imm18_scale2:
1274bb60c28SZi Xuan Wu     if (!isIntN(19, Value))
1284bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
1294bb60c28SZi Xuan Wu     if (Value & 0x1)
1304bb60c28SZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
1314bb60c28SZi Xuan Wu 
1324bb60c28SZi Xuan Wu     return (Value >> 1) & 0x3ffff;
133582836faSZi Xuan Wu   case CSKY::fixup_csky_pcrel_uimm8_scale4: {
134582836faSZi Xuan Wu     if (!isUIntN(10, Value))
135582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
136582836faSZi Xuan Wu     if (Value & 0x3)
137582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
138582836faSZi Xuan Wu 
139582836faSZi Xuan Wu     unsigned IMM4L = (Value >> 2) & 0xf;
140582836faSZi Xuan Wu     unsigned IMM4H = (Value >> 6) & 0xf;
141582836faSZi Xuan Wu 
142582836faSZi Xuan Wu     Value = (IMM4H << 21) | (IMM4L << 4);
143582836faSZi Xuan Wu     return Value;
144582836faSZi Xuan Wu   }
145582836faSZi Xuan Wu   case CSKY::fixup_csky_pcrel_imm10_scale2:
146582836faSZi Xuan Wu     if (!isIntN(11, Value))
147582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
148582836faSZi Xuan Wu     if (Value & 0x1)
149582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");
150582836faSZi Xuan Wu 
151582836faSZi Xuan Wu     return (Value >> 1) & 0x3ff;
152582836faSZi Xuan Wu   case CSKY::fixup_csky_pcrel_uimm7_scale4:
153582836faSZi Xuan Wu     if (!isUIntN(9, Value))
154582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
155582836faSZi Xuan Wu     if (Value & 0x3)
156582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
157582836faSZi Xuan Wu 
158582836faSZi Xuan Wu     if ((Value & 0xff) <= 0b111111100) {
159582836faSZi Xuan Wu       unsigned IMM5L = (Value >> 2) & 0x1f;
160582836faSZi Xuan Wu       unsigned IMM2H = (Value >> 7) & 0x3;
161582836faSZi Xuan Wu 
162582836faSZi Xuan Wu       Value = (1 << 12) | (IMM2H << 8) | IMM5L;
163582836faSZi Xuan Wu     } else {
164582836faSZi Xuan Wu       unsigned IMM5L = (!Value >> 2) & 0x1f;
165582836faSZi Xuan Wu       unsigned IMM2H = (!Value >> 7) & 0x3;
166582836faSZi Xuan Wu 
167582836faSZi Xuan Wu       Value = (IMM2H << 8) | IMM5L;
168582836faSZi Xuan Wu     }
169582836faSZi Xuan Wu 
170582836faSZi Xuan Wu     return Value & 0xffff;
171582836faSZi Xuan Wu   }
172582836faSZi Xuan Wu }
173582836faSZi Xuan Wu 
fixupNeedsRelaxationAdvanced(const MCFixup & Fixup,bool Resolved,uint64_t Value,const MCRelaxableFragment * DF,const MCAsmLayout & Layout,const bool WasForced) const174582836faSZi Xuan Wu bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
175582836faSZi Xuan Wu                                                   bool Resolved, uint64_t Value,
176582836faSZi Xuan Wu                                                   const MCRelaxableFragment *DF,
177582836faSZi Xuan Wu                                                   const MCAsmLayout &Layout,
178582836faSZi Xuan Wu                                                   const bool WasForced) const {
179582836faSZi Xuan Wu   // Return true if the symbol is actually unresolved.
180582836faSZi Xuan Wu   // Resolved could be always false when shouldForceRelocation return true.
181582836faSZi Xuan Wu   // We use !WasForced to indicate that the symbol is unresolved and not forced
182582836faSZi Xuan Wu   // by shouldForceRelocation.
183582836faSZi Xuan Wu   if (!Resolved && !WasForced)
184582836faSZi Xuan Wu     return true;
185582836faSZi Xuan Wu 
186582836faSZi Xuan Wu   int64_t Offset = int64_t(Value);
187582836faSZi Xuan Wu   switch (Fixup.getTargetKind()) {
188582836faSZi Xuan Wu   default:
189582836faSZi Xuan Wu     return false;
190582836faSZi Xuan Wu   case CSKY::fixup_csky_pcrel_imm10_scale2:
191582836faSZi Xuan Wu     return !isShiftedInt<10, 1>(Offset);
192582836faSZi Xuan Wu   case CSKY::fixup_csky_pcrel_imm16_scale2:
193582836faSZi Xuan Wu     return !isShiftedInt<16, 1>(Offset);
194582836faSZi Xuan Wu   case CSKY::fixup_csky_pcrel_imm26_scale2:
195582836faSZi Xuan Wu     return !isShiftedInt<26, 1>(Offset);
196582836faSZi Xuan Wu   case CSKY::fixup_csky_pcrel_uimm7_scale4:
197582836faSZi Xuan Wu     return !isShiftedUInt<8, 2>(Offset);
1984bb60c28SZi Xuan Wu   }
1994bb60c28SZi Xuan Wu }
200ec17c4f0SZi Xuan Wu 
applyFixup(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,MutableArrayRef<char> Data,uint64_t Value,bool IsResolved,const MCSubtargetInfo * STI) const201ec17c4f0SZi Xuan Wu void CSKYAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
202ec17c4f0SZi Xuan Wu                                 const MCValue &Target,
203ec17c4f0SZi Xuan Wu                                 MutableArrayRef<char> Data, uint64_t Value,
204ec17c4f0SZi Xuan Wu                                 bool IsResolved,
205ec17c4f0SZi Xuan Wu                                 const MCSubtargetInfo *STI) const {
2064bb60c28SZi Xuan Wu   MCFixupKind Kind = Fixup.getKind();
2074bb60c28SZi Xuan Wu   if (Kind >= FirstLiteralRelocationKind)
208ec17c4f0SZi Xuan Wu     return;
2094bb60c28SZi Xuan Wu   MCContext &Ctx = Asm.getContext();
2104bb60c28SZi Xuan Wu   MCFixupKindInfo Info = getFixupKindInfo(Kind);
2114bb60c28SZi Xuan Wu   if (!Value)
2124bb60c28SZi Xuan Wu     return; // Doesn't change encoding.
2134bb60c28SZi Xuan Wu   // Apply any target-specific value adjustments.
2144bb60c28SZi Xuan Wu   Value = adjustFixupValue(Fixup, Value, Ctx);
2154bb60c28SZi Xuan Wu 
2164bb60c28SZi Xuan Wu   // Shift the value into position.
2174bb60c28SZi Xuan Wu   Value <<= Info.TargetOffset;
2184bb60c28SZi Xuan Wu 
2194bb60c28SZi Xuan Wu   unsigned Offset = Fixup.getOffset();
2204bb60c28SZi Xuan Wu   unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8;
2214bb60c28SZi Xuan Wu 
2224bb60c28SZi Xuan Wu   assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
2234bb60c28SZi Xuan Wu 
2244bb60c28SZi Xuan Wu   // For each byte of the fragment that the fixup touches, mask in the
2254bb60c28SZi Xuan Wu   // bits from the fixup value.
2264bb60c28SZi Xuan Wu   bool IsLittleEndian = (Endian == support::little);
2270365c54cSZi Xuan Wu   bool IsInstFixup = (Kind >= FirstTargetFixupKind);
2284bb60c28SZi Xuan Wu 
2290365c54cSZi Xuan Wu   if (IsLittleEndian && IsInstFixup && (NumBytes == 4)) {
2304bb60c28SZi Xuan Wu     Data[Offset + 0] |= uint8_t((Value >> 16) & 0xff);
2314bb60c28SZi Xuan Wu     Data[Offset + 1] |= uint8_t((Value >> 24) & 0xff);
2324bb60c28SZi Xuan Wu     Data[Offset + 2] |= uint8_t(Value & 0xff);
2334bb60c28SZi Xuan Wu     Data[Offset + 3] |= uint8_t((Value >> 8) & 0xff);
2344bb60c28SZi Xuan Wu   } else {
2354bb60c28SZi Xuan Wu     for (unsigned I = 0; I != NumBytes; I++) {
2364bb60c28SZi Xuan Wu       unsigned Idx = IsLittleEndian ? I : (NumBytes - 1 - I);
2374bb60c28SZi Xuan Wu       Data[Offset + Idx] |= uint8_t((Value >> (I * 8)) & 0xff);
2384bb60c28SZi Xuan Wu     }
2394bb60c28SZi Xuan Wu   }
240ec17c4f0SZi Xuan Wu }
241ec17c4f0SZi Xuan Wu 
mayNeedRelaxation(const MCInst & Inst,const MCSubtargetInfo & STI) const242582836faSZi Xuan Wu bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst,
243582836faSZi Xuan Wu                                        const MCSubtargetInfo &STI) const {
244582836faSZi Xuan Wu   switch (Inst.getOpcode()) {
245582836faSZi Xuan Wu   default:
246582836faSZi Xuan Wu     return false;
247582836faSZi Xuan Wu   case CSKY::JBR32:
248582836faSZi Xuan Wu   case CSKY::JBT32:
249582836faSZi Xuan Wu   case CSKY::JBF32:
250582836faSZi Xuan Wu   case CSKY::JBSR32:
251582836faSZi Xuan Wu     if (!STI.getFeatureBits()[CSKY::Has2E3])
252582836faSZi Xuan Wu       return false;
253582836faSZi Xuan Wu     return true;
254582836faSZi Xuan Wu   case CSKY::JBR16:
255582836faSZi Xuan Wu   case CSKY::JBT16:
256582836faSZi Xuan Wu   case CSKY::JBF16:
257582836faSZi Xuan Wu   case CSKY::LRW16:
258582836faSZi Xuan Wu   case CSKY::BR16:
259582836faSZi Xuan Wu     return true;
260582836faSZi Xuan Wu   }
261582836faSZi Xuan Wu }
262582836faSZi Xuan Wu 
shouldForceRelocation(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target)263582836faSZi Xuan Wu bool CSKYAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
264582836faSZi Xuan Wu                                            const MCFixup &Fixup,
265582836faSZi Xuan Wu                                            const MCValue &Target) {
266582836faSZi Xuan Wu   if (Fixup.getKind() >= FirstLiteralRelocationKind)
267582836faSZi Xuan Wu     return true;
268582836faSZi Xuan Wu   switch (Fixup.getTargetKind()) {
269582836faSZi Xuan Wu   default:
270582836faSZi Xuan Wu     break;
271582836faSZi Xuan Wu   case CSKY::fixup_csky_got32:
272582836faSZi Xuan Wu   case CSKY::fixup_csky_got_imm18_scale4:
273582836faSZi Xuan Wu   case CSKY::fixup_csky_gotoff:
274582836faSZi Xuan Wu   case CSKY::fixup_csky_gotpc:
275582836faSZi Xuan Wu   case CSKY::fixup_csky_plt32:
276582836faSZi Xuan Wu   case CSKY::fixup_csky_plt_imm18_scale4:
277582836faSZi Xuan Wu   case CSKY::fixup_csky_doffset_imm18:
278582836faSZi Xuan Wu   case CSKY::fixup_csky_doffset_imm18_scale2:
279582836faSZi Xuan Wu   case CSKY::fixup_csky_doffset_imm18_scale4:
280582836faSZi Xuan Wu     return true;
281582836faSZi Xuan Wu   }
282582836faSZi Xuan Wu 
283582836faSZi Xuan Wu   return false;
284582836faSZi Xuan Wu }
285582836faSZi Xuan Wu 
fixupNeedsRelaxation(const MCFixup & Fixup,uint64_t Value,const MCRelaxableFragment * DF,const MCAsmLayout & Layout) const286ec17c4f0SZi Xuan Wu bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
287ec17c4f0SZi Xuan Wu                                           const MCRelaxableFragment *DF,
288ec17c4f0SZi Xuan Wu                                           const MCAsmLayout &Layout) const {
289ec17c4f0SZi Xuan Wu   return false;
290ec17c4f0SZi Xuan Wu }
291ec17c4f0SZi Xuan Wu 
relaxInstruction(MCInst & Inst,const MCSubtargetInfo & STI) const292ec17c4f0SZi Xuan Wu void CSKYAsmBackend::relaxInstruction(MCInst &Inst,
293ec17c4f0SZi Xuan Wu                                       const MCSubtargetInfo &STI) const {
294582836faSZi Xuan Wu   MCInst Res;
295582836faSZi Xuan Wu 
296582836faSZi Xuan Wu   switch (Inst.getOpcode()) {
297582836faSZi Xuan Wu   default:
298*481e2ddeSKees Cook     LLVM_DEBUG(Inst.dump());
299582836faSZi Xuan Wu     llvm_unreachable("Opcode not expected!");
300582836faSZi Xuan Wu   case CSKY::LRW16:
301582836faSZi Xuan Wu     Res.setOpcode(CSKY::LRW32);
302582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(0));
303582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(1));
304582836faSZi Xuan Wu     break;
305582836faSZi Xuan Wu   case CSKY::BR16:
306582836faSZi Xuan Wu     Res.setOpcode(CSKY::BR32);
307582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(0));
308582836faSZi Xuan Wu     break;
309582836faSZi Xuan Wu   case CSKY::JBSR32:
310582836faSZi Xuan Wu     Res.setOpcode(CSKY::JSRI32);
311582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(1));
312582836faSZi Xuan Wu     break;
313582836faSZi Xuan Wu   case CSKY::JBR32:
314582836faSZi Xuan Wu     Res.setOpcode(CSKY::JMPI32);
315582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(1));
316582836faSZi Xuan Wu     break;
317582836faSZi Xuan Wu   case CSKY::JBT32:
318582836faSZi Xuan Wu   case CSKY::JBF32:
319582836faSZi Xuan Wu     Res.setOpcode(Inst.getOpcode() == CSKY::JBT32 ? CSKY::JBT_E : CSKY::JBF_E);
320582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(0));
321582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(1));
322582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(2));
323582836faSZi Xuan Wu     break;
324582836faSZi Xuan Wu   case CSKY::JBR16:
325582836faSZi Xuan Wu     Res.setOpcode(CSKY::JBR32);
326582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(0));
327582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(1));
328582836faSZi Xuan Wu     break;
329582836faSZi Xuan Wu   case CSKY::JBT16:
330582836faSZi Xuan Wu   case CSKY::JBF16:
331582836faSZi Xuan Wu     // ck801
332582836faSZi Xuan Wu     unsigned opcode;
333582836faSZi Xuan Wu     if (STI.getFeatureBits()[CSKY::HasE2])
334582836faSZi Xuan Wu       opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT32 : CSKY::JBF32;
335582836faSZi Xuan Wu     else
336582836faSZi Xuan Wu       opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT_E : CSKY::JBF_E;
337582836faSZi Xuan Wu 
338582836faSZi Xuan Wu     Res.setOpcode(opcode);
339582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(0));
340582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(1));
341582836faSZi Xuan Wu     Res.addOperand(Inst.getOperand(2));
342582836faSZi Xuan Wu     break;
343582836faSZi Xuan Wu   }
344582836faSZi Xuan Wu   Inst = std::move(Res);
345ec17c4f0SZi Xuan Wu }
346ec17c4f0SZi Xuan Wu 
writeNopData(raw_ostream & OS,uint64_t Count,const MCSubtargetInfo * STI) const347e63455d5SPeter Smith bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
348e63455d5SPeter Smith                                   const MCSubtargetInfo *STI) const {
349582836faSZi Xuan Wu   OS.write_zeros(Count);
350ec17c4f0SZi Xuan Wu   return true;
351ec17c4f0SZi Xuan Wu }
352ec17c4f0SZi Xuan Wu 
createCSKYAsmBackend(const Target & T,const MCSubtargetInfo & STI,const MCRegisterInfo & MRI,const MCTargetOptions & Options)353ec17c4f0SZi Xuan Wu MCAsmBackend *llvm::createCSKYAsmBackend(const Target &T,
354ec17c4f0SZi Xuan Wu                                          const MCSubtargetInfo &STI,
355ec17c4f0SZi Xuan Wu                                          const MCRegisterInfo &MRI,
356ec17c4f0SZi Xuan Wu                                          const MCTargetOptions &Options) {
357ec17c4f0SZi Xuan Wu   return new CSKYAsmBackend(STI, Options);
358ec17c4f0SZi Xuan Wu }
359