LLVM API Documentation
00001 //===-- SystemZMCAsmBackend.cpp - SystemZ assembler backend ---------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MCTargetDesc/SystemZMCTargetDesc.h" 00011 #include "MCTargetDesc/SystemZMCFixups.h" 00012 #include "llvm/MC/MCAsmBackend.h" 00013 #include "llvm/MC/MCELFObjectWriter.h" 00014 #include "llvm/MC/MCFixupKindInfo.h" 00015 #include "llvm/MC/MCInst.h" 00016 #include "llvm/MC/MCObjectWriter.h" 00017 00018 using namespace llvm; 00019 00020 // Value is a fully-resolved relocation value: Symbol + Addend [- Pivot]. 00021 // Return the bits that should be installed in a relocation field for 00022 // fixup kind Kind. 00023 static uint64_t extractBitsForFixup(MCFixupKind Kind, uint64_t Value) { 00024 if (Kind < FirstTargetFixupKind) 00025 return Value; 00026 00027 switch (unsigned(Kind)) { 00028 case SystemZ::FK_390_PC16DBL: 00029 case SystemZ::FK_390_PC32DBL: 00030 case SystemZ::FK_390_PLT16DBL: 00031 case SystemZ::FK_390_PLT32DBL: 00032 return (int64_t)Value / 2; 00033 } 00034 00035 llvm_unreachable("Unknown fixup kind!"); 00036 } 00037 00038 namespace { 00039 class SystemZMCAsmBackend : public MCAsmBackend { 00040 uint8_t OSABI; 00041 public: 00042 SystemZMCAsmBackend(uint8_t osABI) 00043 : OSABI(osABI) {} 00044 00045 // Override MCAsmBackend 00046 unsigned getNumFixupKinds() const override { 00047 return SystemZ::NumTargetFixupKinds; 00048 } 00049 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; 00050 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 00051 uint64_t Value, bool IsPCRel) const override; 00052 bool mayNeedRelaxation(const MCInst &Inst) const override { 00053 return false; 00054 } 00055 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 00056 const MCRelaxableFragment *Fragment, 00057 const MCAsmLayout &Layout) const override { 00058 return false; 00059 } 00060 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override { 00061 llvm_unreachable("SystemZ does do not have assembler relaxation"); 00062 } 00063 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; 00064 MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 00065 return createSystemZObjectWriter(OS, OSABI); 00066 } 00067 }; 00068 } // end anonymous namespace 00069 00070 const MCFixupKindInfo & 00071 SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { 00072 const static MCFixupKindInfo Infos[SystemZ::NumTargetFixupKinds] = { 00073 { "FK_390_PC16DBL", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 00074 { "FK_390_PC32DBL", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 00075 { "FK_390_PLT16DBL", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 00076 { "FK_390_PLT32DBL", 0, 32, MCFixupKindInfo::FKF_IsPCRel } 00077 }; 00078 00079 if (Kind < FirstTargetFixupKind) 00080 return MCAsmBackend::getFixupKindInfo(Kind); 00081 00082 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 00083 "Invalid kind!"); 00084 return Infos[Kind - FirstTargetFixupKind]; 00085 } 00086 00087 void SystemZMCAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, 00088 unsigned DataSize, uint64_t Value, 00089 bool IsPCRel) const { 00090 MCFixupKind Kind = Fixup.getKind(); 00091 unsigned Offset = Fixup.getOffset(); 00092 unsigned Size = (getFixupKindInfo(Kind).TargetSize + 7) / 8; 00093 00094 assert(Offset + Size <= DataSize && "Invalid fixup offset!"); 00095 00096 // Big-endian insertion of Size bytes. 00097 Value = extractBitsForFixup(Kind, Value); 00098 unsigned ShiftValue = (Size * 8) - 8; 00099 for (unsigned I = 0; I != Size; ++I) { 00100 Data[Offset + I] |= uint8_t(Value >> ShiftValue); 00101 ShiftValue -= 8; 00102 } 00103 } 00104 00105 bool SystemZMCAsmBackend::writeNopData(uint64_t Count, 00106 MCObjectWriter *OW) const { 00107 for (uint64_t I = 0; I != Count; ++I) 00108 OW->Write8(7); 00109 return true; 00110 } 00111 00112 MCAsmBackend *llvm::createSystemZMCAsmBackend(const Target &T, 00113 const MCRegisterInfo &MRI, 00114 StringRef TT, StringRef CPU) { 00115 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); 00116 return new SystemZMCAsmBackend(OSABI); 00117 }