LLVM API Documentation

SystemZMCAsmBackend.cpp
Go to the documentation of this file.
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 }