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/MCAsmLayout.h" 13e8d8bef9SDimitry Andric #include "llvm/MC/MCAssembler.h" 14e8d8bef9SDimitry Andric #include "llvm/MC/MCContext.h" 15e8d8bef9SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h" 16e8d8bef9SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 17e8d8bef9SDimitry Andric #include "llvm/Support/Debug.h" 18e8d8bef9SDimitry Andric 19e8d8bef9SDimitry Andric #define DEBUG_TYPE "csky-asmbackend" 20e8d8bef9SDimitry Andric 21e8d8bef9SDimitry Andric using namespace llvm; 22e8d8bef9SDimitry Andric 23e8d8bef9SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 24e8d8bef9SDimitry Andric CSKYAsmBackend::createObjectTargetWriter() const { 25e8d8bef9SDimitry Andric return createCSKYELFObjectWriter(); 26e8d8bef9SDimitry Andric } 27e8d8bef9SDimitry Andric 28fe6060f1SDimitry Andric const MCFixupKindInfo & 29fe6060f1SDimitry Andric CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { 30fe6060f1SDimitry Andric 31fe6060f1SDimitry Andric static llvm::DenseMap<unsigned, MCFixupKindInfo> Infos = { 32fe6060f1SDimitry Andric {CSKY::Fixups::fixup_csky_addr32, {"fixup_csky_addr32", 0, 32, 0}}, 33349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_addr_hi16, {"fixup_csky_addr_hi16", 0, 32, 0}}, 34349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_addr_lo16, {"fixup_csky_addr_lo16", 0, 32, 0}}, 35fe6060f1SDimitry Andric {CSKY::Fixups::fixup_csky_pcrel_imm16_scale2, 36fe6060f1SDimitry Andric {"fixup_csky_pcrel_imm16_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, 37fe6060f1SDimitry Andric {CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4, 38349cc55cSDimitry Andric {"fixup_csky_pcrel_uimm16_scale4", 0, 32, 39349cc55cSDimitry Andric MCFixupKindInfo::FKF_IsPCRel | 40349cc55cSDimitry Andric MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}}, 41349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4, 42349cc55cSDimitry Andric {"fixup_csky_pcrel_uimm8_scale4", 0, 32, 43349cc55cSDimitry Andric MCFixupKindInfo::FKF_IsPCRel | 44349cc55cSDimitry Andric MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}}, 45fe6060f1SDimitry Andric {CSKY::Fixups::fixup_csky_pcrel_imm26_scale2, 46fe6060f1SDimitry Andric {"fixup_csky_pcrel_imm26_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, 47fe6060f1SDimitry Andric {CSKY::Fixups::fixup_csky_pcrel_imm18_scale2, 48349cc55cSDimitry Andric {"fixup_csky_pcrel_imm18_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, 49349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_got32, {"fixup_csky_got32", 0, 32, 0}}, 50349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_got_imm18_scale4, 51349cc55cSDimitry Andric {"fixup_csky_got_imm18_scale4", 0, 32, 0}}, 52349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_gotoff, {"fixup_csky_gotoff", 0, 32, 0}}, 53349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_gotpc, 54349cc55cSDimitry Andric {"fixup_csky_gotpc", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}, 55349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_plt32, {"fixup_csky_plt32", 0, 32, 0}}, 56349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_plt_imm18_scale4, 57349cc55cSDimitry Andric {"fixup_csky_plt_imm18_scale4", 0, 32, 0}}, 58349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_pcrel_imm10_scale2, 59349cc55cSDimitry Andric {"fixup_csky_pcrel_imm10_scale2", 0, 16, MCFixupKindInfo::FKF_IsPCRel}}, 60349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4, 61349cc55cSDimitry Andric {"fixup_csky_pcrel_uimm7_scale4", 0, 16, 62349cc55cSDimitry Andric MCFixupKindInfo::FKF_IsPCRel | 63349cc55cSDimitry Andric MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}}, 64349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_doffset_imm18, 65349cc55cSDimitry Andric {"fixup_csky_doffset_imm18", 0, 18, 0}}, 66349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_doffset_imm18_scale2, 67349cc55cSDimitry Andric {"fixup_csky_doffset_imm18_scale2", 0, 18, 0}}, 68349cc55cSDimitry Andric {CSKY::Fixups::fixup_csky_doffset_imm18_scale4, 69349cc55cSDimitry Andric {"fixup_csky_doffset_imm18_scale4", 0, 18, 0}}}; 70349cc55cSDimitry Andric 71fe6060f1SDimitry Andric assert(Infos.size() == CSKY::NumTargetFixupKinds && 72fe6060f1SDimitry Andric "Not all fixup kinds added to Infos array"); 73fe6060f1SDimitry Andric 74349cc55cSDimitry Andric if (FirstTargetFixupKind <= Kind && Kind < FirstLiteralRelocationKind) { 75fe6060f1SDimitry Andric assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 76fe6060f1SDimitry Andric "Invalid kind!"); 77349cc55cSDimitry Andric 78fe6060f1SDimitry Andric return Infos[Kind]; 79349cc55cSDimitry Andric } else if (Kind < FirstTargetFixupKind) { 80fe6060f1SDimitry Andric return MCAsmBackend::getFixupKindInfo(Kind); 81349cc55cSDimitry Andric } else { 82fe6060f1SDimitry Andric return MCAsmBackend::getFixupKindInfo(FK_NONE); 83fe6060f1SDimitry Andric } 84349cc55cSDimitry Andric } 85fe6060f1SDimitry Andric 86fe6060f1SDimitry Andric static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, 87fe6060f1SDimitry Andric MCContext &Ctx) { 88fe6060f1SDimitry Andric switch (Fixup.getTargetKind()) { 89fe6060f1SDimitry Andric default: 90fe6060f1SDimitry Andric llvm_unreachable("Unknown fixup kind!"); 9181ad6265SDimitry Andric case CSKY::fixup_csky_got32: 9281ad6265SDimitry Andric case CSKY::fixup_csky_got_imm18_scale4: 9381ad6265SDimitry Andric case CSKY::fixup_csky_gotoff: 9481ad6265SDimitry Andric case CSKY::fixup_csky_gotpc: 9581ad6265SDimitry Andric case CSKY::fixup_csky_plt32: 9681ad6265SDimitry Andric case CSKY::fixup_csky_plt_imm18_scale4: 9781ad6265SDimitry Andric llvm_unreachable("Relocation should be unconditionally forced\n"); 98fe6060f1SDimitry Andric case FK_Data_1: 99fe6060f1SDimitry Andric case FK_Data_2: 100fe6060f1SDimitry Andric case FK_Data_4: 101fe6060f1SDimitry Andric case FK_Data_8: 102fe6060f1SDimitry Andric return Value; 103fe6060f1SDimitry Andric case CSKY::fixup_csky_addr32: 104fe6060f1SDimitry Andric return Value & 0xffffffff; 105fe6060f1SDimitry Andric case CSKY::fixup_csky_pcrel_imm16_scale2: 106fe6060f1SDimitry Andric if (!isIntN(17, Value)) 107fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); 108fe6060f1SDimitry Andric if (Value & 0x1) 109fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned."); 110fe6060f1SDimitry Andric 111fe6060f1SDimitry Andric return (Value >> 1) & 0xffff; 112fe6060f1SDimitry Andric case CSKY::fixup_csky_pcrel_uimm16_scale4: 113fe6060f1SDimitry Andric if (!isUIntN(18, Value)) 114fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); 115fe6060f1SDimitry Andric if (Value & 0x3) 116fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned."); 117fe6060f1SDimitry Andric 118fe6060f1SDimitry Andric return (Value >> 2) & 0xffff; 119fe6060f1SDimitry Andric case CSKY::fixup_csky_pcrel_imm26_scale2: 120fe6060f1SDimitry Andric if (!isIntN(27, Value)) 121fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); 122fe6060f1SDimitry Andric if (Value & 0x1) 123fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned."); 124fe6060f1SDimitry Andric 125fe6060f1SDimitry Andric return (Value >> 1) & 0x3ffffff; 126fe6060f1SDimitry Andric case CSKY::fixup_csky_pcrel_imm18_scale2: 127fe6060f1SDimitry Andric if (!isIntN(19, Value)) 128fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); 129fe6060f1SDimitry Andric if (Value & 0x1) 130fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned."); 131fe6060f1SDimitry Andric 132fe6060f1SDimitry Andric return (Value >> 1) & 0x3ffff; 13381ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_uimm8_scale4: { 13481ad6265SDimitry Andric if (!isUIntN(10, Value)) 13581ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); 13681ad6265SDimitry Andric if (Value & 0x3) 13781ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned."); 13881ad6265SDimitry Andric 13981ad6265SDimitry Andric unsigned IMM4L = (Value >> 2) & 0xf; 14081ad6265SDimitry Andric unsigned IMM4H = (Value >> 6) & 0xf; 14181ad6265SDimitry Andric 14281ad6265SDimitry Andric Value = (IMM4H << 21) | (IMM4L << 4); 14381ad6265SDimitry Andric return Value; 14481ad6265SDimitry Andric } 14581ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm10_scale2: 14681ad6265SDimitry Andric if (!isIntN(11, Value)) 14781ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); 14881ad6265SDimitry Andric if (Value & 0x1) 14981ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned."); 15081ad6265SDimitry Andric 15181ad6265SDimitry Andric return (Value >> 1) & 0x3ff; 15281ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_uimm7_scale4: 153bdd1243dSDimitry Andric if ((Value >> 2) > 0xfe) 15481ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); 15581ad6265SDimitry Andric if (Value & 0x3) 15681ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned."); 15781ad6265SDimitry Andric 158bdd1243dSDimitry Andric if ((Value >> 2) <= 0x7f) { 15981ad6265SDimitry Andric unsigned IMM5L = (Value >> 2) & 0x1f; 16081ad6265SDimitry Andric unsigned IMM2H = (Value >> 7) & 0x3; 16181ad6265SDimitry Andric 16281ad6265SDimitry Andric Value = (1 << 12) | (IMM2H << 8) | IMM5L; 16381ad6265SDimitry Andric } else { 164bdd1243dSDimitry Andric unsigned IMM5L = (~Value >> 2) & 0x1f; 165bdd1243dSDimitry Andric unsigned IMM2H = (~Value >> 7) & 0x3; 16681ad6265SDimitry Andric 16781ad6265SDimitry Andric Value = (IMM2H << 8) | IMM5L; 16881ad6265SDimitry Andric } 16981ad6265SDimitry Andric 170bdd1243dSDimitry Andric return Value; 17181ad6265SDimitry Andric } 17281ad6265SDimitry Andric } 17381ad6265SDimitry Andric 17481ad6265SDimitry Andric bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, 17581ad6265SDimitry Andric bool Resolved, uint64_t Value, 17681ad6265SDimitry Andric const MCRelaxableFragment *DF, 17781ad6265SDimitry Andric const MCAsmLayout &Layout, 17881ad6265SDimitry Andric const bool WasForced) const { 17981ad6265SDimitry Andric // Return true if the symbol is actually unresolved. 18081ad6265SDimitry Andric // Resolved could be always false when shouldForceRelocation return true. 18181ad6265SDimitry Andric // We use !WasForced to indicate that the symbol is unresolved and not forced 18281ad6265SDimitry Andric // by shouldForceRelocation. 18381ad6265SDimitry Andric if (!Resolved && !WasForced) 18481ad6265SDimitry Andric return true; 18581ad6265SDimitry Andric 18681ad6265SDimitry Andric int64_t Offset = int64_t(Value); 18781ad6265SDimitry Andric switch (Fixup.getTargetKind()) { 18881ad6265SDimitry Andric default: 18981ad6265SDimitry Andric return false; 19081ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm10_scale2: 19181ad6265SDimitry Andric return !isShiftedInt<10, 1>(Offset); 19281ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm16_scale2: 19381ad6265SDimitry Andric return !isShiftedInt<16, 1>(Offset); 19481ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm26_scale2: 19581ad6265SDimitry Andric return !isShiftedInt<26, 1>(Offset); 19681ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_uimm7_scale4: 197bdd1243dSDimitry Andric return ((Value >> 2) > 0xfe) || (Value & 0x3); 198fe6060f1SDimitry Andric } 199fe6060f1SDimitry Andric } 200e8d8bef9SDimitry Andric 201e8d8bef9SDimitry Andric void CSKYAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, 202e8d8bef9SDimitry Andric const MCValue &Target, 203e8d8bef9SDimitry Andric MutableArrayRef<char> Data, uint64_t Value, 204e8d8bef9SDimitry Andric bool IsResolved, 205e8d8bef9SDimitry Andric const MCSubtargetInfo *STI) const { 206fe6060f1SDimitry Andric MCFixupKind Kind = Fixup.getKind(); 207fe6060f1SDimitry Andric if (Kind >= FirstLiteralRelocationKind) 208e8d8bef9SDimitry Andric return; 209fe6060f1SDimitry Andric MCContext &Ctx = Asm.getContext(); 210fe6060f1SDimitry Andric MCFixupKindInfo Info = getFixupKindInfo(Kind); 211fe6060f1SDimitry Andric if (!Value) 212fe6060f1SDimitry Andric return; // Doesn't change encoding. 213fe6060f1SDimitry Andric // Apply any target-specific value adjustments. 214fe6060f1SDimitry Andric Value = adjustFixupValue(Fixup, Value, Ctx); 215fe6060f1SDimitry Andric 216fe6060f1SDimitry Andric // Shift the value into position. 217fe6060f1SDimitry Andric Value <<= Info.TargetOffset; 218fe6060f1SDimitry Andric 219fe6060f1SDimitry Andric unsigned Offset = Fixup.getOffset(); 220fe6060f1SDimitry Andric unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8; 221fe6060f1SDimitry Andric 222fe6060f1SDimitry Andric assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!"); 223fe6060f1SDimitry Andric 224fe6060f1SDimitry Andric // For each byte of the fragment that the fixup touches, mask in the 225fe6060f1SDimitry Andric // bits from the fixup value. 226*5f757f3fSDimitry Andric bool IsLittleEndian = (Endian == llvm::endianness::little); 22781ad6265SDimitry Andric bool IsInstFixup = (Kind >= FirstTargetFixupKind); 228fe6060f1SDimitry Andric 22981ad6265SDimitry Andric if (IsLittleEndian && IsInstFixup && (NumBytes == 4)) { 230fe6060f1SDimitry Andric Data[Offset + 0] |= uint8_t((Value >> 16) & 0xff); 231fe6060f1SDimitry Andric Data[Offset + 1] |= uint8_t((Value >> 24) & 0xff); 232fe6060f1SDimitry Andric Data[Offset + 2] |= uint8_t(Value & 0xff); 233fe6060f1SDimitry Andric Data[Offset + 3] |= uint8_t((Value >> 8) & 0xff); 234fe6060f1SDimitry Andric } else { 235fe6060f1SDimitry Andric for (unsigned I = 0; I != NumBytes; I++) { 236fe6060f1SDimitry Andric unsigned Idx = IsLittleEndian ? I : (NumBytes - 1 - I); 237fe6060f1SDimitry Andric Data[Offset + Idx] |= uint8_t((Value >> (I * 8)) & 0xff); 238fe6060f1SDimitry Andric } 239fe6060f1SDimitry Andric } 240e8d8bef9SDimitry Andric } 241e8d8bef9SDimitry Andric 24281ad6265SDimitry Andric bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst, 24381ad6265SDimitry Andric const MCSubtargetInfo &STI) const { 24481ad6265SDimitry Andric switch (Inst.getOpcode()) { 24581ad6265SDimitry Andric default: 24681ad6265SDimitry Andric return false; 24781ad6265SDimitry Andric case CSKY::JBR32: 24881ad6265SDimitry Andric case CSKY::JBT32: 24981ad6265SDimitry Andric case CSKY::JBF32: 25081ad6265SDimitry Andric case CSKY::JBSR32: 25106c3fb27SDimitry Andric if (!STI.hasFeature(CSKY::Has2E3)) 25281ad6265SDimitry Andric return false; 25381ad6265SDimitry Andric return true; 25481ad6265SDimitry Andric case CSKY::JBR16: 25581ad6265SDimitry Andric case CSKY::JBT16: 25681ad6265SDimitry Andric case CSKY::JBF16: 25781ad6265SDimitry Andric case CSKY::LRW16: 25881ad6265SDimitry Andric case CSKY::BR16: 25981ad6265SDimitry Andric return true; 26081ad6265SDimitry Andric } 26181ad6265SDimitry Andric } 26281ad6265SDimitry Andric 26381ad6265SDimitry Andric bool CSKYAsmBackend::shouldForceRelocation(const MCAssembler &Asm, 26481ad6265SDimitry Andric const MCFixup &Fixup, 265*5f757f3fSDimitry Andric const MCValue &Target, 266*5f757f3fSDimitry Andric const MCSubtargetInfo * /*STI*/) { 26781ad6265SDimitry Andric if (Fixup.getKind() >= FirstLiteralRelocationKind) 26881ad6265SDimitry Andric return true; 26981ad6265SDimitry Andric switch (Fixup.getTargetKind()) { 27081ad6265SDimitry Andric default: 27181ad6265SDimitry Andric break; 27281ad6265SDimitry Andric case CSKY::fixup_csky_got32: 27381ad6265SDimitry Andric case CSKY::fixup_csky_got_imm18_scale4: 27481ad6265SDimitry Andric case CSKY::fixup_csky_gotoff: 27581ad6265SDimitry Andric case CSKY::fixup_csky_gotpc: 27681ad6265SDimitry Andric case CSKY::fixup_csky_plt32: 27781ad6265SDimitry Andric case CSKY::fixup_csky_plt_imm18_scale4: 27881ad6265SDimitry Andric case CSKY::fixup_csky_doffset_imm18: 27981ad6265SDimitry Andric case CSKY::fixup_csky_doffset_imm18_scale2: 28081ad6265SDimitry Andric case CSKY::fixup_csky_doffset_imm18_scale4: 28181ad6265SDimitry Andric return true; 28281ad6265SDimitry Andric } 28381ad6265SDimitry Andric 28481ad6265SDimitry Andric return false; 28581ad6265SDimitry Andric } 28681ad6265SDimitry Andric 287e8d8bef9SDimitry Andric bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 288e8d8bef9SDimitry Andric const MCRelaxableFragment *DF, 289e8d8bef9SDimitry Andric const MCAsmLayout &Layout) const { 290e8d8bef9SDimitry Andric return false; 291e8d8bef9SDimitry Andric } 292e8d8bef9SDimitry Andric 293e8d8bef9SDimitry Andric void CSKYAsmBackend::relaxInstruction(MCInst &Inst, 294e8d8bef9SDimitry Andric const MCSubtargetInfo &STI) const { 29581ad6265SDimitry Andric MCInst Res; 29681ad6265SDimitry Andric 29781ad6265SDimitry Andric switch (Inst.getOpcode()) { 29881ad6265SDimitry Andric default: 29981ad6265SDimitry Andric LLVM_DEBUG(Inst.dump()); 30081ad6265SDimitry Andric llvm_unreachable("Opcode not expected!"); 30181ad6265SDimitry Andric case CSKY::LRW16: 30281ad6265SDimitry Andric Res.setOpcode(CSKY::LRW32); 30381ad6265SDimitry Andric Res.addOperand(Inst.getOperand(0)); 30481ad6265SDimitry Andric Res.addOperand(Inst.getOperand(1)); 30581ad6265SDimitry Andric break; 30681ad6265SDimitry Andric case CSKY::BR16: 30781ad6265SDimitry Andric Res.setOpcode(CSKY::BR32); 30881ad6265SDimitry Andric Res.addOperand(Inst.getOperand(0)); 30981ad6265SDimitry Andric break; 31081ad6265SDimitry Andric case CSKY::JBSR32: 31181ad6265SDimitry Andric Res.setOpcode(CSKY::JSRI32); 31281ad6265SDimitry Andric Res.addOperand(Inst.getOperand(1)); 31381ad6265SDimitry Andric break; 31481ad6265SDimitry Andric case CSKY::JBR32: 31581ad6265SDimitry Andric Res.setOpcode(CSKY::JMPI32); 31681ad6265SDimitry Andric Res.addOperand(Inst.getOperand(1)); 31781ad6265SDimitry Andric break; 31881ad6265SDimitry Andric case CSKY::JBT32: 31981ad6265SDimitry Andric case CSKY::JBF32: 32081ad6265SDimitry Andric Res.setOpcode(Inst.getOpcode() == CSKY::JBT32 ? CSKY::JBT_E : CSKY::JBF_E); 32181ad6265SDimitry Andric Res.addOperand(Inst.getOperand(0)); 32281ad6265SDimitry Andric Res.addOperand(Inst.getOperand(1)); 32381ad6265SDimitry Andric Res.addOperand(Inst.getOperand(2)); 32481ad6265SDimitry Andric break; 32581ad6265SDimitry Andric case CSKY::JBR16: 32681ad6265SDimitry Andric Res.setOpcode(CSKY::JBR32); 32781ad6265SDimitry Andric Res.addOperand(Inst.getOperand(0)); 32881ad6265SDimitry Andric Res.addOperand(Inst.getOperand(1)); 32981ad6265SDimitry Andric break; 33081ad6265SDimitry Andric case CSKY::JBT16: 33181ad6265SDimitry Andric case CSKY::JBF16: 33281ad6265SDimitry Andric // ck801 33381ad6265SDimitry Andric unsigned opcode; 33406c3fb27SDimitry Andric if (STI.hasFeature(CSKY::HasE2)) 33581ad6265SDimitry Andric opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT32 : CSKY::JBF32; 33681ad6265SDimitry Andric else 33781ad6265SDimitry Andric opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT_E : CSKY::JBF_E; 33881ad6265SDimitry Andric 33981ad6265SDimitry Andric Res.setOpcode(opcode); 34081ad6265SDimitry Andric Res.addOperand(Inst.getOperand(0)); 34181ad6265SDimitry Andric Res.addOperand(Inst.getOperand(1)); 34281ad6265SDimitry Andric Res.addOperand(Inst.getOperand(2)); 34381ad6265SDimitry Andric break; 34481ad6265SDimitry Andric } 34581ad6265SDimitry Andric Inst = std::move(Res); 346e8d8bef9SDimitry Andric } 347e8d8bef9SDimitry Andric 348349cc55cSDimitry Andric bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, 349349cc55cSDimitry Andric const MCSubtargetInfo *STI) const { 35081ad6265SDimitry Andric OS.write_zeros(Count); 351e8d8bef9SDimitry Andric return true; 352e8d8bef9SDimitry Andric } 353e8d8bef9SDimitry Andric 354e8d8bef9SDimitry Andric MCAsmBackend *llvm::createCSKYAsmBackend(const Target &T, 355e8d8bef9SDimitry Andric const MCSubtargetInfo &STI, 356e8d8bef9SDimitry Andric const MCRegisterInfo &MRI, 357e8d8bef9SDimitry Andric const MCTargetOptions &Options) { 358e8d8bef9SDimitry Andric return new CSKYAsmBackend(STI, Options); 359e8d8bef9SDimitry Andric } 360