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>
createObjectTargetWriter() const23e8d8bef9SDimitry Andric CSKYAsmBackend::createObjectTargetWriter() const {
24e8d8bef9SDimitry Andric return createCSKYELFObjectWriter();
25e8d8bef9SDimitry Andric }
26e8d8bef9SDimitry Andric
27fe6060f1SDimitry Andric const MCFixupKindInfo &
getFixupKindInfo(MCFixupKind Kind) const28fe6060f1SDimitry 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
adjustFixupValue(const MCFixup & Fixup,uint64_t Value,MCContext & Ctx)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
fixupNeedsRelaxationAdvanced(const MCAssembler & Asm,const MCFixup & Fixup,bool Resolved,uint64_t Value,const MCRelaxableFragment * DF,const bool WasForced) const173*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
applyFixup(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,MutableArrayRef<char> Data,uint64_t Value,bool IsResolved,const MCSubtargetInfo * STI) const200e8d8bef9SDimitry 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
mayNeedRelaxation(const MCInst & Inst,const MCSubtargetInfo & STI) const24181ad6265SDimitry 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
shouldForceRelocation(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,const MCSubtargetInfo *)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
fixupNeedsRelaxation(const MCFixup & Fixup,uint64_t Value) const286*0fca6ea1SDimitry Andric bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
287*0fca6ea1SDimitry Andric uint64_t Value) const {
288e8d8bef9SDimitry Andric return false;
289e8d8bef9SDimitry Andric }
290e8d8bef9SDimitry Andric
relaxInstruction(MCInst & Inst,const MCSubtargetInfo & STI) const291e8d8bef9SDimitry 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
writeNopData(raw_ostream & OS,uint64_t Count,const MCSubtargetInfo * STI) const346349cc55cSDimitry 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
createCSKYAsmBackend(const Target & T,const MCSubtargetInfo & STI,const MCRegisterInfo & MRI,const MCTargetOptions & Options)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