Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp @ 120:1172e4bd9c6f
update 4.0.0
author | mir3636 |
---|---|
date | Fri, 25 Nov 2016 19:14:25 +0900 |
parents | |
children | 803732b1fca8 |
comparison
equal
deleted
inserted
replaced
101:34baf5011add | 120:1172e4bd9c6f |
---|---|
1 //===-- LanaiAsmBackend.cpp - Lanai 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 "LanaiFixupKinds.h" | |
11 #include "MCTargetDesc/LanaiMCTargetDesc.h" | |
12 #include "llvm/MC/MCAsmBackend.h" | |
13 #include "llvm/MC/MCAssembler.h" | |
14 #include "llvm/MC/MCDirectives.h" | |
15 #include "llvm/MC/MCELFObjectWriter.h" | |
16 #include "llvm/MC/MCFixupKindInfo.h" | |
17 #include "llvm/MC/MCObjectWriter.h" | |
18 #include "llvm/MC/MCSubtargetInfo.h" | |
19 #include "llvm/Support/ErrorHandling.h" | |
20 #include "llvm/Support/raw_ostream.h" | |
21 | |
22 using namespace llvm; | |
23 | |
24 // Prepare value for the target space | |
25 static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { | |
26 switch (Kind) { | |
27 case FK_Data_1: | |
28 case FK_Data_2: | |
29 case FK_Data_4: | |
30 case FK_Data_8: | |
31 return Value; | |
32 case Lanai::FIXUP_LANAI_21: | |
33 case Lanai::FIXUP_LANAI_21_F: | |
34 case Lanai::FIXUP_LANAI_25: | |
35 case Lanai::FIXUP_LANAI_32: | |
36 case Lanai::FIXUP_LANAI_HI16: | |
37 case Lanai::FIXUP_LANAI_LO16: | |
38 return Value; | |
39 default: | |
40 llvm_unreachable("Unknown fixup kind!"); | |
41 } | |
42 } | |
43 | |
44 namespace { | |
45 class LanaiAsmBackend : public MCAsmBackend { | |
46 Triple::OSType OSType; | |
47 | |
48 public: | |
49 LanaiAsmBackend(const Target &T, Triple::OSType OST) | |
50 : MCAsmBackend(), OSType(OST) {} | |
51 | |
52 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, | |
53 uint64_t Value, bool IsPCRel) const override; | |
54 | |
55 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; | |
56 | |
57 // No instruction requires relaxation | |
58 bool fixupNeedsRelaxation(const MCFixup & /*Fixup*/, uint64_t /*Value*/, | |
59 const MCRelaxableFragment * /*DF*/, | |
60 const MCAsmLayout & /*Layout*/) const override { | |
61 return false; | |
62 } | |
63 | |
64 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; | |
65 | |
66 unsigned getNumFixupKinds() const override { | |
67 return Lanai::NumTargetFixupKinds; | |
68 } | |
69 | |
70 bool mayNeedRelaxation(const MCInst & /*Inst*/) const override { | |
71 return false; | |
72 } | |
73 | |
74 void relaxInstruction(const MCInst & /*Inst*/, | |
75 const MCSubtargetInfo & /*STI*/, | |
76 MCInst & /*Res*/) const override {} | |
77 | |
78 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; | |
79 }; | |
80 | |
81 bool LanaiAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { | |
82 if ((Count % 4) != 0) | |
83 return false; | |
84 | |
85 for (uint64_t i = 0; i < Count; i += 4) | |
86 OW->write32(0x15000000); | |
87 | |
88 return true; | |
89 } | |
90 | |
91 void LanaiAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, | |
92 unsigned /*DataSize*/, uint64_t Value, | |
93 bool /*IsPCRel*/) const { | |
94 MCFixupKind Kind = Fixup.getKind(); | |
95 Value = adjustFixupValue(static_cast<unsigned>(Kind), Value); | |
96 | |
97 if (!Value) | |
98 return; // This value doesn't change the encoding | |
99 | |
100 // Where in the object and where the number of bytes that need | |
101 // fixing up | |
102 unsigned Offset = Fixup.getOffset(); | |
103 unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8; | |
104 unsigned FullSize = 4; | |
105 | |
106 // Grab current value, if any, from bits. | |
107 uint64_t CurVal = 0; | |
108 | |
109 // Load instruction and apply value | |
110 for (unsigned i = 0; i != NumBytes; ++i) { | |
111 unsigned Idx = (FullSize - 1 - i); | |
112 CurVal |= static_cast<uint64_t>(static_cast<uint8_t>(Data[Offset + Idx])) | |
113 << (i * 8); | |
114 } | |
115 | |
116 uint64_t Mask = | |
117 (static_cast<uint64_t>(-1) >> (64 - getFixupKindInfo(Kind).TargetSize)); | |
118 CurVal |= Value & Mask; | |
119 | |
120 // Write out the fixed up bytes back to the code/data bits. | |
121 for (unsigned i = 0; i != NumBytes; ++i) { | |
122 unsigned Idx = (FullSize - 1 - i); | |
123 Data[Offset + Idx] = static_cast<uint8_t>((CurVal >> (i * 8)) & 0xff); | |
124 } | |
125 } | |
126 | |
127 MCObjectWriter * | |
128 LanaiAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { | |
129 return createLanaiELFObjectWriter(OS, | |
130 MCELFObjectTargetWriter::getOSABI(OSType)); | |
131 } | |
132 | |
133 const MCFixupKindInfo & | |
134 LanaiAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { | |
135 static const MCFixupKindInfo Infos[Lanai::NumTargetFixupKinds] = { | |
136 // This table *must* be in same the order of fixup_* kinds in | |
137 // LanaiFixupKinds.h. | |
138 // Note: The number of bits indicated here are assumed to be contiguous. | |
139 // This does not hold true for LANAI_21 and LANAI_21_F which are applied | |
140 // to bits 0x7cffff and 0x7cfffc, respectively. Since the 'bits' counts | |
141 // here are used only for cosmetic purposes, we set the size to 16 bits | |
142 // for these 21-bit relocation as llvm/lib/MC/MCAsmStreamer.cpp checks | |
143 // no bits are set in the fixup range. | |
144 // | |
145 // name offset bits flags | |
146 {"FIXUP_LANAI_NONE", 0, 32, 0}, | |
147 {"FIXUP_LANAI_21", 16, 16 /*21*/, 0}, | |
148 {"FIXUP_LANAI_21_F", 16, 16 /*21*/, 0}, | |
149 {"FIXUP_LANAI_25", 7, 25, 0}, | |
150 {"FIXUP_LANAI_32", 0, 32, 0}, | |
151 {"FIXUP_LANAI_HI16", 16, 16, 0}, | |
152 {"FIXUP_LANAI_LO16", 16, 16, 0}}; | |
153 | |
154 if (Kind < FirstTargetFixupKind) | |
155 return MCAsmBackend::getFixupKindInfo(Kind); | |
156 | |
157 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && | |
158 "Invalid kind!"); | |
159 return Infos[Kind - FirstTargetFixupKind]; | |
160 } | |
161 | |
162 } // namespace | |
163 | |
164 MCAsmBackend *llvm::createLanaiAsmBackend(const Target &T, | |
165 const MCRegisterInfo & /*MRI*/, | |
166 const Triple &TT, StringRef /*CPU*/, | |
167 const MCTargetOptions & /*Options*/) { | |
168 if (!TT.isOSBinFormatELF()) | |
169 llvm_unreachable("OS not supported"); | |
170 | |
171 return new LanaiAsmBackend(T, TT.getOS()); | |
172 } |