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