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