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