Skip to content

Commit 9fb4dc5

Browse files
committed
OR1K: Added basic ELFWriter
This code needs to handle all relocations correctly
1 parent 6948dec commit 9fb4dc5

13 files changed

+430
-2
lines changed

README.or1k

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ TODO (not a complete list)
2828
- Handle unconditional branches in AnalyzeBranch
2929
- Floating point support
3030
- Integrated assembler support
31+
- Relocations

include/llvm/Support/ELF.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,17 @@ enum {
765765
R_HEX_TPREL_11_X = 85
766766
};
767767

768+
// ELF Relocation Types for OpenRISC 1000
769+
enum {
770+
R_OR32_NONE = 0,
771+
R_OR32_32 = 1,
772+
R_OR32_16 = 2,
773+
R_OR32_8 = 3,
774+
R_OR32_CONST = 4,
775+
R_OR32_CONSTH = 5,
776+
R_OR32_JUMPTARG = 6
777+
};
778+
768779
// Section header.
769780
struct Elf32_Shdr {
770781
Elf32_Word sh_name; // Section name (index into string table)

lib/Target/OR1K/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_llvm_target(OR1KCodeGen
2525
OR1KSelectionDAGInfo.cpp
2626
OR1KAsmPrinter.cpp
2727
OR1KMCInstLower.cpp
28+
OR1KELFWriterInfo.cpp
2829
)
2930

3031
add_subdirectory(InstPrinter)
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
add_llvm_library(LLVMOR1KDesc
2-
OR1KMCTargetDesc.cpp
2+
OR1KAsmBackend.cpp
33
OR1KMCAsmInfo.cpp
44
OR1KMCCodeEmitter.cpp
5+
OR1KMCTargetDesc.cpp
56
)
67

78
add_dependencies(LLVMOR1KDesc OR1KCommonTableGen)
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
//===-- OR1KAsmBackend.cpp - OR1K Assembler Backend -----------------------===//
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/OR1KMCTargetDesc.h"
11+
#include "llvm/MC/MCAsmBackend.h"
12+
#include "llvm/MC/MCAssembler.h"
13+
#include "llvm/MC/MCAsmLayout.h"
14+
#include "llvm/MC/MCELFObjectWriter.h"
15+
#include "llvm/MC/MCELFSymbolFlags.h"
16+
#include "llvm/MC/MCExpr.h"
17+
#include "llvm/MC/MCObjectWriter.h"
18+
#include "llvm/MC/MCSectionELF.h"
19+
#include "llvm/MC/MCSectionMachO.h"
20+
#include "llvm/MC/MCValue.h"
21+
#include "llvm/ADT/Twine.h"
22+
#include "llvm/Support/ELF.h"
23+
#include "llvm/Support/ErrorHandling.h"
24+
#include "llvm/Support/TargetRegistry.h"
25+
#include "llvm/Support/raw_ostream.h"
26+
using namespace llvm;
27+
28+
static unsigned getFixupKindSize(unsigned Kind) {
29+
switch (Kind) {
30+
default: llvm_unreachable("invalid fixup kind!");
31+
case FK_Data_1: return 1;
32+
case FK_Data_2: return 2;
33+
case FK_Data_4: return 4;
34+
}
35+
}
36+
37+
namespace {
38+
39+
class OR1KAsmBackend : public MCAsmBackend {
40+
public:
41+
OR1KAsmBackend(const Target &T)
42+
: MCAsmBackend() {
43+
}
44+
45+
unsigned getNumFixupKinds() const {
46+
// FIXME: Is this correct?
47+
return 0;
48+
}
49+
50+
bool mayNeedRelaxation(const MCInst &Inst) const;
51+
52+
bool fixupNeedsRelaxation(const MCFixup &Fixup,
53+
uint64_t Value,
54+
const MCInstFragment *DF,
55+
const MCAsmLayout &Layout) const;
56+
57+
void relaxInstruction(const MCInst &Inst, MCInst &Res) const;
58+
59+
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const;
60+
61+
unsigned getPointerSize() const {
62+
return 4;
63+
}
64+
};
65+
66+
static unsigned getRelaxedOpcode(unsigned Op) {
67+
// FIXME: All opcodes are already their relaxed opcode?
68+
switch (Op) {
69+
default: return Op;
70+
}
71+
}
72+
73+
74+
bool OR1KAsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
75+
// FIXME: Looking at the Code Emitter list of opcodes, it looks like none of
76+
// these need relaxation. Add a comparison for opcode if this is incorrect.
77+
return false;
78+
}
79+
80+
bool OR1KAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
81+
uint64_t Value,
82+
const MCInstFragment *DF,
83+
const MCAsmLayout &Layout) const {
84+
// FIXME: Looking at the Code Emitter list of opcodes, it looks like none of
85+
// these need relaxation. Add a comparison for opcode if this is incorrect.
86+
return false;
87+
}
88+
89+
void OR1KAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
90+
// FIXME: From above comment, no instruction needs relaxation so this function
91+
// does nothing.
92+
}
93+
94+
bool OR1KAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
95+
if ((Count % 4) != 0)
96+
return false;
97+
98+
for (uint64_t i = 0; i < Count; i += 4)
99+
OW->Write32(0x00000015);
100+
101+
return true;
102+
}
103+
} // end anonymous namespace
104+
105+
namespace {
106+
class ELFOR1KAsmBackend : public OR1KAsmBackend {
107+
public:
108+
uint8_t OSABI;
109+
ELFOR1KAsmBackend(const Target &T, uint8_t _OSABI)
110+
: OR1KAsmBackend(T), OSABI(_OSABI) {}
111+
112+
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
113+
uint64_t Value) const;
114+
115+
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
116+
return createOR1KELFObjectWriter(OS, OSABI);
117+
}
118+
};
119+
120+
void ELFOR1KAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
121+
unsigned DataSize, uint64_t Value) const {
122+
// FIXME: Implement with real fixups used.
123+
unsigned Size = getFixupKindSize(Fixup.getKind());
124+
125+
assert(Fixup.getOffset() + Size <= DataSize && "Invalid fixup offset!");
126+
switch(Size) {
127+
default: llvm_unreachable("Cannot fixup unknown value");
128+
}
129+
}
130+
} // end anonymous namespace
131+
132+
MCAsmBackend *llvm::createOR1KAsmBackend(const Target &T, StringRef TT) {
133+
Triple TheTriple(TT);
134+
135+
if (TheTriple.isOSDarwin())
136+
assert(0 && "Mac not supported on OR1K");
137+
138+
if (TheTriple.isOSWindows())
139+
assert(0 && "Windows not supported on OR1K");
140+
141+
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
142+
return new ELFOR1KAsmBackend(T, OSABI);
143+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===-- OR1KELFObjectWriter.cpp - OR1K 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/OR1KMCTargetDesc.h"
11+
#include "llvm/MC/MCELFObjectWriter.h"
12+
#include "llvm/MC/MCFixup.h"
13+
#include "llvm/Support/ErrorHandling.h"
14+
#include "llvm/Support/raw_ostream.h"
15+
16+
using namespace llvm;
17+
18+
namespace {
19+
class OR1KELFObjectWriter : public MCELFObjectTargetWriter {
20+
public:
21+
OR1KELFObjectWriter(uint8_t OSABI);
22+
23+
virtual ~OR1KELFObjectWriter();
24+
protected:
25+
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
26+
bool IsPCRel, bool IsRelocWithSymbol,
27+
int64_t Addend) const;
28+
};
29+
}
30+
31+
OR1KELFObjectWriter::OR1KELFObjectWriter(uint8_t OSABI)
32+
: MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_OPENRISC,
33+
/*HasRelocationAddend*/ true) {}
34+
35+
OR1KELFObjectWriter::~OR1KELFObjectWriter() {}
36+
37+
unsigned OR1KELFObjectWriter::GetRelocType(const MCValue &Target,
38+
const MCFixup &Fixup,
39+
bool IsPCRel,
40+
bool IsRelocWithSymbol,
41+
int64_t Addend) const {
42+
unsigned Type;
43+
switch ((unsigned)Fixup.getKind()) {
44+
default: llvm_unreachable("Invalid fixup kind!");
45+
case FK_Data_4:
46+
Type = ELF::R_OR32_32;
47+
break;
48+
case FK_Data_2:
49+
Type = ELF::R_OR32_16;
50+
break;
51+
case FK_Data_1:
52+
Type = ELF::R_OR32_8;
53+
break;
54+
}
55+
return Type;
56+
}
57+
58+
MCObjectWriter *llvm::createOR1KELFObjectWriter(raw_ostream &OS,
59+
uint8_t OSABI) {
60+
MCELFObjectTargetWriter *MOTW = new OR1KELFObjectWriter(OSABI);
61+
return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/ false);
62+
}

lib/Target/OR1K/MCTargetDesc/OR1KMCTargetDesc.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/MC/MCCodeGenInfo.h"
1818
#include "llvm/MC/MCInstrInfo.h"
1919
#include "llvm/MC/MCRegisterInfo.h"
20+
#include "llvm/MC/MCStreamer.h"
2021
#include "llvm/MC/MCSubtargetInfo.h"
2122
#include "llvm/Support/ErrorHandling.h"
2223
#include "llvm/Support/TargetRegistry.h"
@@ -59,6 +60,25 @@ static MCCodeGenInfo *createOR1KMCCodeGenInfo(StringRef TT, Reloc::Model RM,
5960
return X;
6061
}
6162

63+
static MCStreamer *createOR1KMCStreamer(const Target &T, StringRef TT,
64+
MCContext &Ctx, MCAsmBackend &MAB,
65+
raw_ostream &_OS,
66+
MCCodeEmitter *_Emitter,
67+
bool RelaxAll,
68+
bool NoExecStack) {
69+
Triple TheTriple(TT);
70+
71+
if (TheTriple.isOSDarwin()) {
72+
llvm_unreachable("OR1K does not support Darwin MACH-O format");
73+
}
74+
75+
if (TheTriple.isOSWindows()) {
76+
llvm_unreachable("OR1K does not support Windows COFF format");
77+
}
78+
79+
return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
80+
}
81+
6282
static MCInstPrinter *createOR1KMCInstPrinter(const Target &T,
6383
unsigned SyntaxVariant,
6484
const MCAsmInfo &MAI,
@@ -92,6 +112,15 @@ extern "C" void LLVMInitializeOR1KTargetMC() {
92112
TargetRegistry::RegisterMCCodeEmitter(TheOR1KTarget,
93113
llvm::createOR1KMCCodeEmitter);
94114

115+
// Register the ASM Backend
116+
TargetRegistry::RegisterMCAsmBackend(TheOR1KTarget,
117+
createOR1KAsmBackend);
118+
119+
// Register the object streamer
120+
TargetRegistry::RegisterMCObjectStreamer(TheOR1KTarget,
121+
createOR1KMCStreamer);
122+
123+
95124
// Register the MCInstPrinter.
96125
TargetRegistry::RegisterMCInstPrinter(TheOR1KTarget,
97126
createOR1KMCInstPrinter);

lib/Target/OR1K/MCTargetDesc/OR1KMCTargetDesc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@
1414
#ifndef OR1KMCTARGETDESC_H
1515
#define OR1KMCTARGETDESC_H
1616

17+
#include "llvm/Support/DataTypes.h"
18+
1719
namespace llvm {
20+
class MCAsmBackend;
1821
class MCCodeEmitter;
1922
class MCContext;
2023
class MCInstrInfo;
24+
class MCObjectWriter;
2125
class MCRegisterInfo;
2226
class MCSubtargetInfo;
2327
class Target;
28+
class StringRef;
29+
class raw_ostream;
2430

2531
extern Target TheOR1KTarget;
2632

@@ -29,6 +35,9 @@ MCCodeEmitter *createOR1KMCCodeEmitter(const MCInstrInfo &MCII,
2935
const MCSubtargetInfo &STI,
3036
MCContext &Ctx);
3137

38+
MCAsmBackend *createOR1KAsmBackend(const Target &T, StringRef TT);
39+
40+
MCObjectWriter *createOR1KELFObjectWriter(raw_ostream &OS, uint8_t OSABI);
3241
} // End llvm namespace
3342

3443
// Defines symbolic names for OR1K registers. This defines a mapping from

0 commit comments

Comments
 (0)