1//===-- MBlazeELFObjectWriter.cpp - MBlaze ELF Writer ---------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/MBlazeMCTargetDesc.h"
11#include "llvm/MC/MCELFObjectWriter.h"
12#include "llvm/MC/MCFixup.h"
13#include "llvm/Support/ErrorHandling.h"
14
15using namespace llvm;
16
17namespace {
18  class MBlazeELFObjectWriter : public MCELFObjectTargetWriter {
19  public:
20    MBlazeELFObjectWriter(uint8_t OSABI);
21
22    virtual ~MBlazeELFObjectWriter();
23  protected:
24    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
25                                  bool IsPCRel, bool IsRelocWithSymbol,
26                                  int64_t Addend) const;
27  };
28}
29
30MBlazeELFObjectWriter::MBlazeELFObjectWriter(uint8_t OSABI)
31  : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_MBLAZE,
32                            /*HasRelocationAddend*/ false) {}
33
34MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
35}
36
37unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
38                                             const MCFixup &Fixup,
39                                             bool IsPCRel,
40                                             bool IsRelocWithSymbol,
41                                             int64_t Addend) const {
42  // determine the type of the relocation
43  unsigned Type;
44  if (IsPCRel) {
45    switch ((unsigned)Fixup.getKind()) {
46    default:
47      llvm_unreachable("Unimplemented");
48    case FK_PCRel_4:
49      Type = ELF::R_MICROBLAZE_64_PCREL;
50      break;
51    case FK_PCRel_2:
52      Type = ELF::R_MICROBLAZE_32_PCREL;
53      break;
54    }
55  } else {
56    switch ((unsigned)Fixup.getKind()) {
57    default: llvm_unreachable("invalid fixup kind!");
58    case FK_Data_4:
59      Type = ((IsRelocWithSymbol || Addend !=0)
60              ? ELF::R_MICROBLAZE_32
61              : ELF::R_MICROBLAZE_64);
62      break;
63    case FK_Data_2:
64      Type = ELF::R_MICROBLAZE_32;
65      break;
66    }
67  }
68  return Type;
69}
70
71
72
73MCObjectWriter *llvm::createMBlazeELFObjectWriter(raw_ostream &OS,
74                                                  uint8_t OSABI) {
75  MCELFObjectTargetWriter *MOTW = new MBlazeELFObjectWriter(OSABI);
76  return createELFObjectWriter(MOTW, OS,  /*IsLittleEndian=*/ false);
77}
78