/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- MipsAsmBackend.cpp - Mips Asm 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 | | // This file implements the MipsAsmBackend class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | // |
14 | | |
15 | | #include "MCTargetDesc/MipsAsmBackend.h" |
16 | | #include "MCTargetDesc/MipsFixupKinds.h" |
17 | | #include "MCTargetDesc/MipsMCExpr.h" |
18 | | #include "MCTargetDesc/MipsMCTargetDesc.h" |
19 | | #include "llvm/MC/MCAsmBackend.h" |
20 | | #include "llvm/MC/MCAssembler.h" |
21 | | #include "llvm/MC/MCContext.h" |
22 | | #include "llvm/MC/MCDirectives.h" |
23 | | #include "llvm/MC/MCELFObjectWriter.h" |
24 | | #include "llvm/MC/MCFixupKindInfo.h" |
25 | | #include "llvm/MC/MCObjectWriter.h" |
26 | | #include "llvm/MC/MCSubtargetInfo.h" |
27 | | #include "llvm/MC/MCTargetOptions.h" |
28 | | #include "llvm/MC/MCValue.h" |
29 | | #include "llvm/Support/ErrorHandling.h" |
30 | | #include "llvm/Support/Format.h" |
31 | | #include "llvm/Support/MathExtras.h" |
32 | | #include "llvm/Support/raw_ostream.h" |
33 | | |
34 | | using namespace llvm; |
35 | | |
36 | | // Prepare value for the target space for it |
37 | | static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, |
38 | 1.51k | MCContext &Ctx) { |
39 | 1.51k | |
40 | 1.51k | unsigned Kind = Fixup.getKind(); |
41 | 1.51k | |
42 | 1.51k | // Add/subtract and shift |
43 | 1.51k | switch (Kind) { |
44 | 89 | default: |
45 | 89 | return 0; |
46 | 297 | case FK_Data_2: |
47 | 297 | case Mips::fixup_Mips_LO16: |
48 | 297 | case Mips::fixup_Mips_GPREL16: |
49 | 297 | case Mips::fixup_Mips_GPOFF_HI: |
50 | 297 | case Mips::fixup_Mips_GPOFF_LO: |
51 | 297 | case Mips::fixup_Mips_GOT_PAGE: |
52 | 297 | case Mips::fixup_Mips_GOT_OFST: |
53 | 297 | case Mips::fixup_Mips_GOT_DISP: |
54 | 297 | case Mips::fixup_Mips_GOT_LO16: |
55 | 297 | case Mips::fixup_Mips_CALL_LO16: |
56 | 297 | case Mips::fixup_MICROMIPS_LO16: |
57 | 297 | case Mips::fixup_MICROMIPS_GOT_PAGE: |
58 | 297 | case Mips::fixup_MICROMIPS_GOT_OFST: |
59 | 297 | case Mips::fixup_MICROMIPS_GOT_DISP: |
60 | 297 | case Mips::fixup_MIPS_PCLO16: |
61 | 297 | Value &= 0xffff; |
62 | 297 | break; |
63 | 687 | case FK_DTPRel_4: |
64 | 687 | case FK_DTPRel_8: |
65 | 687 | case FK_TPRel_4: |
66 | 687 | case FK_TPRel_8: |
67 | 687 | case FK_GPRel_4: |
68 | 687 | case FK_Data_4: |
69 | 687 | case FK_Data_8: |
70 | 687 | case Mips::fixup_Mips_SUB: |
71 | 687 | case Mips::fixup_MICROMIPS_SUB: |
72 | 687 | break; |
73 | 80 | case Mips::fixup_Mips_PC16: |
74 | 80 | // The displacement is then divided by 4 to give us an 18 bit |
75 | 80 | // address range. Forcing a signed division because Value can be negative. |
76 | 80 | Value = (int64_t)Value / 4; |
77 | 80 | // We now check if Value can be encoded as a 16-bit signed immediate. |
78 | 80 | if (!isInt<16>(Value)80 ) { |
79 | 2 | Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup"); |
80 | 2 | return 0; |
81 | 2 | } |
82 | 78 | break; |
83 | 21 | case Mips::fixup_MIPS_PC19_S2: |
84 | 21 | case Mips::fixup_MICROMIPS_PC19_S2: |
85 | 21 | // Forcing a signed division because Value can be negative. |
86 | 21 | Value = (int64_t)Value / 4; |
87 | 21 | // We now check if Value can be encoded as a 19-bit signed immediate. |
88 | 21 | if (!isInt<19>(Value)21 ) { |
89 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC19 fixup"); |
90 | 0 | return 0; |
91 | 0 | } |
92 | 21 | break; |
93 | 56 | case Mips::fixup_Mips_26: |
94 | 56 | // So far we are only using this type for jumps. |
95 | 56 | // The displacement is then divided by 4 to give us an 28 bit |
96 | 56 | // address range. |
97 | 56 | Value >>= 2; |
98 | 56 | break; |
99 | 192 | case Mips::fixup_Mips_HI16: |
100 | 192 | case Mips::fixup_Mips_GOT: |
101 | 192 | case Mips::fixup_MICROMIPS_GOT16: |
102 | 192 | case Mips::fixup_Mips_GOT_HI16: |
103 | 192 | case Mips::fixup_Mips_CALL_HI16: |
104 | 192 | case Mips::fixup_MICROMIPS_HI16: |
105 | 192 | case Mips::fixup_MIPS_PCHI16: |
106 | 192 | // Get the 2nd 16-bits. Also add 1 if bit 15 is 1. |
107 | 192 | Value = ((Value + 0x8000) >> 16) & 0xffff; |
108 | 192 | break; |
109 | 10 | case Mips::fixup_Mips_HIGHER: |
110 | 10 | // Get the 3rd 16-bits. |
111 | 10 | Value = ((Value + 0x80008000LL) >> 32) & 0xffff; |
112 | 10 | break; |
113 | 10 | case Mips::fixup_Mips_HIGHEST: |
114 | 10 | // Get the 4th 16-bits. |
115 | 10 | Value = ((Value + 0x800080008000LL) >> 48) & 0xffff; |
116 | 10 | break; |
117 | 7 | case Mips::fixup_MICROMIPS_26_S1: |
118 | 7 | Value >>= 1; |
119 | 7 | break; |
120 | 4 | case Mips::fixup_MICROMIPS_PC7_S1: |
121 | 4 | Value -= 4; |
122 | 4 | // Forcing a signed division because Value can be negative. |
123 | 4 | Value = (int64_t) Value / 2; |
124 | 4 | // We now check if Value can be encoded as a 7-bit signed immediate. |
125 | 4 | if (!isInt<7>(Value)4 ) { |
126 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC7 fixup"); |
127 | 0 | return 0; |
128 | 0 | } |
129 | 4 | break; |
130 | 3 | case Mips::fixup_MICROMIPS_PC10_S1: |
131 | 3 | Value -= 2; |
132 | 3 | // Forcing a signed division because Value can be negative. |
133 | 3 | Value = (int64_t) Value / 2; |
134 | 3 | // We now check if Value can be encoded as a 10-bit signed immediate. |
135 | 3 | if (!isInt<10>(Value)3 ) { |
136 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC10 fixup"); |
137 | 0 | return 0; |
138 | 0 | } |
139 | 3 | break; |
140 | 18 | case Mips::fixup_MICROMIPS_PC16_S1: |
141 | 18 | Value -= 4; |
142 | 18 | // Forcing a signed division because Value can be negative. |
143 | 18 | Value = (int64_t)Value / 2; |
144 | 18 | // We now check if Value can be encoded as a 16-bit signed immediate. |
145 | 18 | if (!isInt<16>(Value)18 ) { |
146 | 2 | Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup"); |
147 | 2 | return 0; |
148 | 2 | } |
149 | 16 | break; |
150 | 5 | case Mips::fixup_MIPS_PC18_S3: |
151 | 5 | // Forcing a signed division because Value can be negative. |
152 | 5 | Value = (int64_t)Value / 8; |
153 | 5 | // We now check if Value can be encoded as a 18-bit signed immediate. |
154 | 5 | if (!isInt<18>(Value)5 ) { |
155 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup"); |
156 | 0 | return 0; |
157 | 0 | } |
158 | 5 | break; |
159 | 1 | case Mips::fixup_MICROMIPS_PC18_S3: |
160 | 1 | // Check alignment. |
161 | 1 | if ((Value & 7)1 ) { |
162 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup"); |
163 | 0 | } |
164 | 1 | // Forcing a signed division because Value can be negative. |
165 | 1 | Value = (int64_t)Value / 8; |
166 | 1 | // We now check if Value can be encoded as a 18-bit signed immediate. |
167 | 1 | if (!isInt<18>(Value)1 ) { |
168 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup"); |
169 | 0 | return 0; |
170 | 0 | } |
171 | 1 | break; |
172 | 16 | case Mips::fixup_MIPS_PC21_S2: |
173 | 16 | // Forcing a signed division because Value can be negative. |
174 | 16 | Value = (int64_t) Value / 4; |
175 | 16 | // We now check if Value can be encoded as a 21-bit signed immediate. |
176 | 16 | if (!isInt<21>(Value)16 ) { |
177 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup"); |
178 | 0 | return 0; |
179 | 0 | } |
180 | 16 | break; |
181 | 11 | case Mips::fixup_MIPS_PC26_S2: |
182 | 11 | // Forcing a signed division because Value can be negative. |
183 | 11 | Value = (int64_t) Value / 4; |
184 | 11 | // We now check if Value can be encoded as a 26-bit signed immediate. |
185 | 11 | if (!isInt<26>(Value)11 ) { |
186 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup"); |
187 | 0 | return 0; |
188 | 0 | } |
189 | 11 | break; |
190 | 4 | case Mips::fixup_MICROMIPS_PC26_S1: |
191 | 4 | // Forcing a signed division because Value can be negative. |
192 | 4 | Value = (int64_t)Value / 2; |
193 | 4 | // We now check if Value can be encoded as a 26-bit signed immediate. |
194 | 4 | if (!isInt<26>(Value)4 ) { |
195 | 0 | Ctx.reportFatalError(Fixup.getLoc(), "out of range PC26 fixup"); |
196 | 0 | return 0; |
197 | 0 | } |
198 | 4 | break; |
199 | 4 | case Mips::fixup_MICROMIPS_PC21_S1: |
200 | 4 | // Forcing a signed division because Value can be negative. |
201 | 4 | Value = (int64_t)Value / 2; |
202 | 4 | // We now check if Value can be encoded as a 21-bit signed immediate. |
203 | 4 | if (!isInt<21>(Value)4 ) { |
204 | 0 | Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup"); |
205 | 0 | return 0; |
206 | 0 | } |
207 | 4 | break; |
208 | 1.42k | } |
209 | 1.42k | |
210 | 1.42k | return Value; |
211 | 1.42k | } |
212 | | |
213 | | MCObjectWriter * |
214 | 462 | MipsAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { |
215 | 462 | return createMipsELFObjectWriter(OS, TheTriple, IsN32); |
216 | 462 | } |
217 | | |
218 | | // Little-endian fixup data byte ordering: |
219 | | // mips32r2: a | b | x | x |
220 | | // microMIPS: x | x | a | b |
221 | | |
222 | 526 | static bool needsMMLEByteOrder(unsigned Kind) { |
223 | 526 | return Kind != Mips::fixup_MICROMIPS_PC10_S1 && |
224 | 523 | Kind >= Mips::fixup_MICROMIPS_26_S1 && |
225 | 44 | Kind < Mips::LastTargetFixupKind; |
226 | 526 | } |
227 | | |
228 | | // Calculate index for microMIPS specific little endian byte order |
229 | 90 | static unsigned calculateMMLEIndex(unsigned i) { |
230 | 90 | assert(i <= 3 && "Index out of range!"); |
231 | 90 | |
232 | 90 | return (1 - i / 2) * 2 + i % 2; |
233 | 90 | } |
234 | | |
235 | | /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided |
236 | | /// data fragment, at the offset specified by the fixup and following the |
237 | | /// fixup kind as appropriate. |
238 | | void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, |
239 | | const MCValue &Target, |
240 | | MutableArrayRef<char> Data, uint64_t Value, |
241 | 1.51k | bool IsResolved) const { |
242 | 1.51k | MCFixupKind Kind = Fixup.getKind(); |
243 | 1.51k | MCContext &Ctx = Asm.getContext(); |
244 | 1.51k | Value = adjustFixupValue(Fixup, Value, Ctx); |
245 | 1.51k | |
246 | 1.51k | if (!Value) |
247 | 989 | return; // Doesn't change encoding. |
248 | 526 | |
249 | 526 | // Where do we start in the object |
250 | 526 | unsigned Offset = Fixup.getOffset(); |
251 | 526 | // Number of bytes we need to fixup |
252 | 526 | unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8; |
253 | 526 | // Used to point to big endian bytes |
254 | 526 | unsigned FullSize; |
255 | 526 | |
256 | 526 | switch ((unsigned)Kind) { |
257 | 6 | case FK_Data_2: |
258 | 6 | case Mips::fixup_Mips_16: |
259 | 6 | case Mips::fixup_MICROMIPS_PC10_S1: |
260 | 6 | FullSize = 2; |
261 | 6 | break; |
262 | 7 | case FK_Data_8: |
263 | 7 | case Mips::fixup_Mips_64: |
264 | 7 | FullSize = 8; |
265 | 7 | break; |
266 | 284 | case FK_Data_4: |
267 | 513 | default: |
268 | 513 | FullSize = 4; |
269 | 513 | break; |
270 | 526 | } |
271 | 526 | |
272 | 526 | // Grab current value, if any, from bits. |
273 | 526 | uint64_t CurVal = 0; |
274 | 526 | |
275 | 526 | bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind); |
276 | 526 | |
277 | 2.26k | for (unsigned i = 0; i != NumBytes2.26k ; ++i1.73k ) { |
278 | 567 | unsigned Idx = IsLittle ? (microMipsLEByteOrder ? 567 calculateMMLEIndex(i)45 |
279 | 567 | : i) |
280 | 1.17k | : (FullSize - 1 - i); |
281 | 1.73k | CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8); |
282 | 1.73k | } |
283 | 526 | |
284 | 526 | uint64_t Mask = ((uint64_t)(-1) >> |
285 | 526 | (64 - getFixupKindInfo(Kind).TargetSize)); |
286 | 526 | CurVal |= Value & Mask; |
287 | 526 | |
288 | 526 | // Write out the fixed up bytes back to the code/data bits. |
289 | 2.26k | for (unsigned i = 0; i != NumBytes2.26k ; ++i1.73k ) { |
290 | 567 | unsigned Idx = IsLittle ? (microMipsLEByteOrder ? 567 calculateMMLEIndex(i)45 |
291 | 567 | : i) |
292 | 1.17k | : (FullSize - 1 - i); |
293 | 1.73k | Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff); |
294 | 1.73k | } |
295 | 1.51k | } |
296 | | |
297 | 12 | Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const { |
298 | 12 | return StringSwitch<Optional<MCFixupKind>>(Name) |
299 | 12 | .Case("R_MIPS_NONE", (MCFixupKind)Mips::fixup_Mips_NONE) |
300 | 12 | .Case("R_MIPS_32", FK_Data_4) |
301 | 12 | .Default(MCAsmBackend::getFixupKind(Name)); |
302 | 12 | } |
303 | | |
304 | | const MCFixupKindInfo &MipsAsmBackend:: |
305 | 7.92k | getFixupKindInfo(MCFixupKind Kind) const { |
306 | 7.92k | const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = { |
307 | 7.92k | // This table *must* be in same the order of fixup_* kinds in |
308 | 7.92k | // MipsFixupKinds.h. |
309 | 7.92k | // |
310 | 7.92k | // name offset bits flags |
311 | 7.92k | { "fixup_Mips_NONE", 0, 0, 0 }, |
312 | 7.92k | { "fixup_Mips_16", 0, 16, 0 }, |
313 | 7.92k | { "fixup_Mips_32", 0, 32, 0 }, |
314 | 7.92k | { "fixup_Mips_REL32", 0, 32, 0 }, |
315 | 7.92k | { "fixup_Mips_26", 0, 26, 0 }, |
316 | 7.92k | { "fixup_Mips_HI16", 0, 16, 0 }, |
317 | 7.92k | { "fixup_Mips_LO16", 0, 16, 0 }, |
318 | 7.92k | { "fixup_Mips_GPREL16", 0, 16, 0 }, |
319 | 7.92k | { "fixup_Mips_LITERAL", 0, 16, 0 }, |
320 | 7.92k | { "fixup_Mips_GOT", 0, 16, 0 }, |
321 | 7.92k | { "fixup_Mips_PC16", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, |
322 | 7.92k | { "fixup_Mips_CALL16", 0, 16, 0 }, |
323 | 7.92k | { "fixup_Mips_GPREL32", 0, 32, 0 }, |
324 | 7.92k | { "fixup_Mips_SHIFT5", 6, 5, 0 }, |
325 | 7.92k | { "fixup_Mips_SHIFT6", 6, 5, 0 }, |
326 | 7.92k | { "fixup_Mips_64", 0, 64, 0 }, |
327 | 7.92k | { "fixup_Mips_TLSGD", 0, 16, 0 }, |
328 | 7.92k | { "fixup_Mips_GOTTPREL", 0, 16, 0 }, |
329 | 7.92k | { "fixup_Mips_TPREL_HI", 0, 16, 0 }, |
330 | 7.92k | { "fixup_Mips_TPREL_LO", 0, 16, 0 }, |
331 | 7.92k | { "fixup_Mips_TLSLDM", 0, 16, 0 }, |
332 | 7.92k | { "fixup_Mips_DTPREL_HI", 0, 16, 0 }, |
333 | 7.92k | { "fixup_Mips_DTPREL_LO", 0, 16, 0 }, |
334 | 7.92k | { "fixup_Mips_Branch_PCRel", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, |
335 | 7.92k | { "fixup_Mips_GPOFF_HI", 0, 16, 0 }, |
336 | 7.92k | { "fixup_Mips_GPOFF_LO", 0, 16, 0 }, |
337 | 7.92k | { "fixup_Mips_GOT_PAGE", 0, 16, 0 }, |
338 | 7.92k | { "fixup_Mips_GOT_OFST", 0, 16, 0 }, |
339 | 7.92k | { "fixup_Mips_GOT_DISP", 0, 16, 0 }, |
340 | 7.92k | { "fixup_Mips_HIGHER", 0, 16, 0 }, |
341 | 7.92k | { "fixup_Mips_HIGHEST", 0, 16, 0 }, |
342 | 7.92k | { "fixup_Mips_GOT_HI16", 0, 16, 0 }, |
343 | 7.92k | { "fixup_Mips_GOT_LO16", 0, 16, 0 }, |
344 | 7.92k | { "fixup_Mips_CALL_HI16", 0, 16, 0 }, |
345 | 7.92k | { "fixup_Mips_CALL_LO16", 0, 16, 0 }, |
346 | 7.92k | { "fixup_Mips_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel }, |
347 | 7.92k | { "fixup_MIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, |
348 | 7.92k | { "fixup_MIPS_PC21_S2", 0, 21, MCFixupKindInfo::FKF_IsPCRel }, |
349 | 7.92k | { "fixup_MIPS_PC26_S2", 0, 26, MCFixupKindInfo::FKF_IsPCRel }, |
350 | 7.92k | { "fixup_MIPS_PCHI16", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, |
351 | 7.92k | { "fixup_MIPS_PCLO16", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, |
352 | 7.92k | { "fixup_MICROMIPS_26_S1", 0, 26, 0 }, |
353 | 7.92k | { "fixup_MICROMIPS_HI16", 0, 16, 0 }, |
354 | 7.92k | { "fixup_MICROMIPS_LO16", 0, 16, 0 }, |
355 | 7.92k | { "fixup_MICROMIPS_GOT16", 0, 16, 0 }, |
356 | 7.92k | { "fixup_MICROMIPS_PC7_S1", 0, 7, MCFixupKindInfo::FKF_IsPCRel }, |
357 | 7.92k | { "fixup_MICROMIPS_PC10_S1", 0, 10, MCFixupKindInfo::FKF_IsPCRel }, |
358 | 7.92k | { "fixup_MICROMIPS_PC16_S1", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, |
359 | 7.92k | { "fixup_MICROMIPS_PC26_S1", 0, 26, MCFixupKindInfo::FKF_IsPCRel }, |
360 | 7.92k | { "fixup_MICROMIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, |
361 | 7.92k | { "fixup_MICROMIPS_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel }, |
362 | 7.92k | { "fixup_MICROMIPS_PC21_S1", 0, 21, MCFixupKindInfo::FKF_IsPCRel }, |
363 | 7.92k | { "fixup_MICROMIPS_CALL16", 0, 16, 0 }, |
364 | 7.92k | { "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 }, |
365 | 7.92k | { "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 }, |
366 | 7.92k | { "fixup_MICROMIPS_GOT_OFST", 0, 16, 0 }, |
367 | 7.92k | { "fixup_MICROMIPS_TLS_GD", 0, 16, 0 }, |
368 | 7.92k | { "fixup_MICROMIPS_TLS_LDM", 0, 16, 0 }, |
369 | 7.92k | { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0, 16, 0 }, |
370 | 7.92k | { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0, 16, 0 }, |
371 | 7.92k | { "fixup_MICROMIPS_GOTTPREL", 0, 16, 0 }, |
372 | 7.92k | { "fixup_MICROMIPS_TLS_TPREL_HI16", 0, 16, 0 }, |
373 | 7.92k | { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 }, |
374 | 7.92k | { "fixup_Mips_SUB", 0, 64, 0 }, |
375 | 7.92k | { "fixup_MICROMIPS_SUB", 0, 64, 0 } |
376 | 7.92k | }; |
377 | 7.92k | |
378 | 7.92k | const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = { |
379 | 7.92k | // This table *must* be in same the order of fixup_* kinds in |
380 | 7.92k | // MipsFixupKinds.h. |
381 | 7.92k | // |
382 | 7.92k | // name offset bits flags |
383 | 7.92k | { "fixup_Mips_NONE", 0, 0, 0 }, |
384 | 7.92k | { "fixup_Mips_16", 16, 16, 0 }, |
385 | 7.92k | { "fixup_Mips_32", 0, 32, 0 }, |
386 | 7.92k | { "fixup_Mips_REL32", 0, 32, 0 }, |
387 | 7.92k | { "fixup_Mips_26", 6, 26, 0 }, |
388 | 7.92k | { "fixup_Mips_HI16", 16, 16, 0 }, |
389 | 7.92k | { "fixup_Mips_LO16", 16, 16, 0 }, |
390 | 7.92k | { "fixup_Mips_GPREL16", 16, 16, 0 }, |
391 | 7.92k | { "fixup_Mips_LITERAL", 16, 16, 0 }, |
392 | 7.92k | { "fixup_Mips_GOT", 16, 16, 0 }, |
393 | 7.92k | { "fixup_Mips_PC16", 16, 16, MCFixupKindInfo::FKF_IsPCRel }, |
394 | 7.92k | { "fixup_Mips_CALL16", 16, 16, 0 }, |
395 | 7.92k | { "fixup_Mips_GPREL32", 0, 32, 0 }, |
396 | 7.92k | { "fixup_Mips_SHIFT5", 21, 5, 0 }, |
397 | 7.92k | { "fixup_Mips_SHIFT6", 21, 5, 0 }, |
398 | 7.92k | { "fixup_Mips_64", 0, 64, 0 }, |
399 | 7.92k | { "fixup_Mips_TLSGD", 16, 16, 0 }, |
400 | 7.92k | { "fixup_Mips_GOTTPREL", 16, 16, 0 }, |
401 | 7.92k | { "fixup_Mips_TPREL_HI", 16, 16, 0 }, |
402 | 7.92k | { "fixup_Mips_TPREL_LO", 16, 16, 0 }, |
403 | 7.92k | { "fixup_Mips_TLSLDM", 16, 16, 0 }, |
404 | 7.92k | { "fixup_Mips_DTPREL_HI", 16, 16, 0 }, |
405 | 7.92k | { "fixup_Mips_DTPREL_LO", 16, 16, 0 }, |
406 | 7.92k | { "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel }, |
407 | 7.92k | { "fixup_Mips_GPOFF_HI", 16, 16, 0 }, |
408 | 7.92k | { "fixup_Mips_GPOFF_LO", 16, 16, 0 }, |
409 | 7.92k | { "fixup_Mips_GOT_PAGE", 16, 16, 0 }, |
410 | 7.92k | { "fixup_Mips_GOT_OFST", 16, 16, 0 }, |
411 | 7.92k | { "fixup_Mips_GOT_DISP", 16, 16, 0 }, |
412 | 7.92k | { "fixup_Mips_HIGHER", 16, 16, 0 }, |
413 | 7.92k | { "fixup_Mips_HIGHEST", 16, 16, 0 }, |
414 | 7.92k | { "fixup_Mips_GOT_HI16", 16, 16, 0 }, |
415 | 7.92k | { "fixup_Mips_GOT_LO16", 16, 16, 0 }, |
416 | 7.92k | { "fixup_Mips_CALL_HI16", 16, 16, 0 }, |
417 | 7.92k | { "fixup_Mips_CALL_LO16", 16, 16, 0 }, |
418 | 7.92k | { "fixup_Mips_PC18_S3", 14, 18, MCFixupKindInfo::FKF_IsPCRel }, |
419 | 7.92k | { "fixup_MIPS_PC19_S2", 13, 19, MCFixupKindInfo::FKF_IsPCRel }, |
420 | 7.92k | { "fixup_MIPS_PC21_S2", 11, 21, MCFixupKindInfo::FKF_IsPCRel }, |
421 | 7.92k | { "fixup_MIPS_PC26_S2", 6, 26, MCFixupKindInfo::FKF_IsPCRel }, |
422 | 7.92k | { "fixup_MIPS_PCHI16", 16, 16, MCFixupKindInfo::FKF_IsPCRel }, |
423 | 7.92k | { "fixup_MIPS_PCLO16", 16, 16, MCFixupKindInfo::FKF_IsPCRel }, |
424 | 7.92k | { "fixup_MICROMIPS_26_S1", 6, 26, 0 }, |
425 | 7.92k | { "fixup_MICROMIPS_HI16", 16, 16, 0 }, |
426 | 7.92k | { "fixup_MICROMIPS_LO16", 16, 16, 0 }, |
427 | 7.92k | { "fixup_MICROMIPS_GOT16", 16, 16, 0 }, |
428 | 7.92k | { "fixup_MICROMIPS_PC7_S1", 9, 7, MCFixupKindInfo::FKF_IsPCRel }, |
429 | 7.92k | { "fixup_MICROMIPS_PC10_S1", 6, 10, MCFixupKindInfo::FKF_IsPCRel }, |
430 | 7.92k | { "fixup_MICROMIPS_PC16_S1",16, 16, MCFixupKindInfo::FKF_IsPCRel }, |
431 | 7.92k | { "fixup_MICROMIPS_PC26_S1", 6, 26, MCFixupKindInfo::FKF_IsPCRel }, |
432 | 7.92k | { "fixup_MICROMIPS_PC19_S2",13, 19, MCFixupKindInfo::FKF_IsPCRel }, |
433 | 7.92k | { "fixup_MICROMIPS_PC18_S3",14, 18, MCFixupKindInfo::FKF_IsPCRel }, |
434 | 7.92k | { "fixup_MICROMIPS_PC21_S1",11, 21, MCFixupKindInfo::FKF_IsPCRel }, |
435 | 7.92k | { "fixup_MICROMIPS_CALL16", 16, 16, 0 }, |
436 | 7.92k | { "fixup_MICROMIPS_GOT_DISP", 16, 16, 0 }, |
437 | 7.92k | { "fixup_MICROMIPS_GOT_PAGE", 16, 16, 0 }, |
438 | 7.92k | { "fixup_MICROMIPS_GOT_OFST", 16, 16, 0 }, |
439 | 7.92k | { "fixup_MICROMIPS_TLS_GD", 16, 16, 0 }, |
440 | 7.92k | { "fixup_MICROMIPS_TLS_LDM", 16, 16, 0 }, |
441 | 7.92k | { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16, 16, 0 }, |
442 | 7.92k | { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16, 16, 0 }, |
443 | 7.92k | { "fixup_MICROMIPS_GOTTPREL", 16, 16, 0 }, |
444 | 7.92k | { "fixup_MICROMIPS_TLS_TPREL_HI16", 16, 16, 0 }, |
445 | 7.92k | { "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 }, |
446 | 7.92k | { "fixup_Mips_SUB", 0, 64, 0 }, |
447 | 7.92k | { "fixup_MICROMIPS_SUB", 0, 64, 0 } |
448 | 7.92k | }; |
449 | 7.92k | |
450 | 7.92k | if (Kind < FirstTargetFixupKind) |
451 | 2.45k | return MCAsmBackend::getFixupKindInfo(Kind); |
452 | 5.47k | |
453 | 7.92k | assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && |
454 | 5.47k | "Invalid kind!"); |
455 | 5.47k | |
456 | 5.47k | if (IsLittle) |
457 | 1.98k | return LittleEndianInfos[Kind - FirstTargetFixupKind]; |
458 | 3.48k | return BigEndianInfos[Kind - FirstTargetFixupKind]; |
459 | 3.48k | } |
460 | | |
461 | | /// WriteNopData - Write an (optimal) nop sequence of Count bytes |
462 | | /// to the given output. If the target cannot generate such a sequence, |
463 | | /// it should return an error. |
464 | | /// |
465 | | /// \return - True on success. |
466 | 651 | bool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { |
467 | 651 | // Check for a less than instruction size number of bytes |
468 | 651 | // FIXME: 16 bit instructions are not handled yet here. |
469 | 651 | // We shouldn't be using a hard coded number for instruction size. |
470 | 651 | |
471 | 651 | // If the count is not 4-byte aligned, we must be writing data into the text |
472 | 651 | // section (otherwise we have unaligned instructions, and thus have far |
473 | 651 | // bigger problems), so just write zeros instead. |
474 | 651 | OW->WriteZeros(Count); |
475 | 651 | return true; |
476 | 651 | } |
477 | | |
478 | | MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, |
479 | | const MCRegisterInfo &MRI, |
480 | | const Triple &TT, StringRef CPU, |
481 | 2.46k | const MCTargetOptions &Options) { |
482 | 2.46k | return new MipsAsmBackend(T, MRI, TT, CPU, Options.ABIName == "n32"); |
483 | 2.46k | } |