OLD | NEW |
---|---|
1 //===-- MipsASMBackend.cpp - Mips Asm Backend ----------------------------===// | 1 //===-- MipsASMBackend.cpp - Mips Asm Backend ----------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the MipsAsmBackend and MipsELFObjectWriter classes. | 10 // This file implements the MipsAsmBackend and MipsELFObjectWriter classes. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 Value = ((Value + 0x8000) >> 16) & 0xffff; | 70 Value = ((Value + 0x8000) >> 16) & 0xffff; |
71 break; | 71 break; |
72 case Mips::fixup_Mips_HIGHER: | 72 case Mips::fixup_Mips_HIGHER: |
73 // Get the 3rd 16-bits. | 73 // Get the 3rd 16-bits. |
74 Value = ((Value + 0x80008000LL) >> 32) & 0xffff; | 74 Value = ((Value + 0x80008000LL) >> 32) & 0xffff; |
75 break; | 75 break; |
76 case Mips::fixup_Mips_HIGHEST: | 76 case Mips::fixup_Mips_HIGHEST: |
77 // Get the 4th 16-bits. | 77 // Get the 4th 16-bits. |
78 Value = ((Value + 0x800080008000LL) >> 48) & 0xffff; | 78 Value = ((Value + 0x800080008000LL) >> 48) & 0xffff; |
79 break; | 79 break; |
80 // @LOCALMOD-START | |
81 case Mips::fixup_Mips_NACL_LONG_BRANCH_HI16: | |
82 // Resolve LUi part of the LUi/ADDiu long branch offset calculation. | |
83 // The Value is the offset of the target basic block from the LUi | |
84 // instruction. Since we need offset from the next instruction (ADDiu), | |
85 // we modify if by -4. Get the high 16-bits. Since the immediate from the | |
86 // ADDiu is treated as signed, add 1 if bit 15 is 1. | |
87 Value = ((Value - 4 + 0x8000) >> 16) & 0xffff; | |
88 break; | |
89 case Mips::fixup_Mips_NACL_LONG_BRANCH_LO16: | |
90 // Resolve ADDiu part of the LUi/ADDiu long branch offset calculation. | |
91 // Get the low 16-bits. | |
92 Value = Value & 0xffff; | |
93 break; | |
94 // @LOCALMOD-END | |
80 } | 95 } |
81 | 96 |
82 return Value; | 97 return Value; |
83 } | 98 } |
84 | 99 |
85 namespace { | 100 namespace { |
86 class MipsAsmBackend : public MCAsmBackend { | 101 class MipsAsmBackend : public MCAsmBackend { |
87 Triple::OSType OSType; | 102 Triple::OSType OSType; |
88 bool IsLittle; // Big or little endian | 103 bool IsLittle; // Big or little endian |
89 bool Is64Bit; // 32 or 64 bit words | 104 bool Is64Bit; // 32 or 64 bit words |
90 | 105 |
91 public: | 106 public: |
92 MipsAsmBackend(const Target &T, Triple::OSType _OSType, | 107 MipsAsmBackend(const Target &T, Triple::OSType _OSType, |
93 bool _isLittle, bool _is64Bit) | 108 bool _isLittle, bool _is64Bit) |
94 :MCAsmBackend(), OSType(_OSType), IsLittle(_isLittle), Is64Bit(_is64Bit) {} | 109 :MCAsmBackend(), OSType(_OSType), IsLittle(_isLittle), Is64Bit(_is64Bit) {} |
95 | 110 |
96 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { | 111 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { |
97 return createMipsELFObjectWriter(OS, | 112 return createMipsELFObjectWriter(OS, |
98 MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit); | 113 MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit); |
99 } | 114 } |
100 | 115 |
116 // @LOCALMOD-START | |
117 /// processFixupValue - Target hook to process the literal value of a fixup | |
118 /// if necessary. | |
119 void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, | |
120 const MCFixup &Fixup, const MCFragment *DF, | |
121 MCValue &Target, uint64_t &Value, | |
122 bool &IsResolved) { | |
123 if (OSType == Triple::NaCl) { | |
Mark Seaborn
2013/10/24 23:38:43
Isn't this check unnecessary? Checking getKind()
petarj
2013/11/21 18:23:42
Done.
| |
124 if ((unsigned)Fixup.getKind() == Mips::fixup_Mips_NACL_LONG_BRANCH_HI16 | |
125 || ((unsigned)Fixup.getKind() | |
126 == Mips::fixup_Mips_NACL_LONG_BRANCH_LO16)) { | |
127 // We don't need to emit relocation for long branch fixup. | |
128 IsResolved = true; | |
129 } | |
130 } | |
131 } | |
132 // @LOCALMOD-END | |
133 | |
101 /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided | 134 /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided |
102 /// data fragment, at the offset specified by the fixup and following the | 135 /// data fragment, at the offset specified by the fixup and following the |
103 /// fixup kind as appropriate. | 136 /// fixup kind as appropriate. |
104 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, | 137 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, |
105 uint64_t Value) const { | 138 uint64_t Value) const { |
106 MCFixupKind Kind = Fixup.getKind(); | 139 MCFixupKind Kind = Fixup.getKind(); |
107 Value = adjustFixupValue((unsigned)Kind, Value); | 140 Value = adjustFixupValue((unsigned)Kind, Value); |
108 | 141 |
109 if (!Value) | 142 if (!Value) |
110 return; // Doesn't change encoding. | 143 return; // Doesn't change encoding. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 { "fixup_Mips_GPOFF_HI", 0, 16, 0 }, | 215 { "fixup_Mips_GPOFF_HI", 0, 16, 0 }, |
183 { "fixup_Mips_GPOFF_LO", 0, 16, 0 }, | 216 { "fixup_Mips_GPOFF_LO", 0, 16, 0 }, |
184 { "fixup_Mips_GOT_PAGE", 0, 16, 0 }, | 217 { "fixup_Mips_GOT_PAGE", 0, 16, 0 }, |
185 { "fixup_Mips_GOT_OFST", 0, 16, 0 }, | 218 { "fixup_Mips_GOT_OFST", 0, 16, 0 }, |
186 { "fixup_Mips_GOT_DISP", 0, 16, 0 }, | 219 { "fixup_Mips_GOT_DISP", 0, 16, 0 }, |
187 { "fixup_Mips_HIGHER", 0, 16, 0 }, | 220 { "fixup_Mips_HIGHER", 0, 16, 0 }, |
188 { "fixup_Mips_HIGHEST", 0, 16, 0 }, | 221 { "fixup_Mips_HIGHEST", 0, 16, 0 }, |
189 { "fixup_Mips_GOT_HI16", 0, 16, 0 }, | 222 { "fixup_Mips_GOT_HI16", 0, 16, 0 }, |
190 { "fixup_Mips_GOT_LO16", 0, 16, 0 }, | 223 { "fixup_Mips_GOT_LO16", 0, 16, 0 }, |
191 { "fixup_Mips_CALL_HI16", 0, 16, 0 }, | 224 { "fixup_Mips_CALL_HI16", 0, 16, 0 }, |
192 { "fixup_Mips_CALL_LO16", 0, 16, 0 } | 225 { "fixup_Mips_CALL_LO16", 0, 16, 0 }, |
226 // @LOCALMOD-START | |
227 { "fixup_Mips_NACL_LONG_BRANCH_HI16", 0, 16, | |
228 MCFixupKindInfo::FKF_IsPCRel }, | |
229 { "fixup_Mips_NACL_LONG_BRANCH_LO16", 0, 16, | |
230 MCFixupKindInfo::FKF_IsPCRel } | |
231 // @LOCALMOD-END | |
193 }; | 232 }; |
194 | 233 |
195 if (Kind < FirstTargetFixupKind) | 234 if (Kind < FirstTargetFixupKind) |
196 return MCAsmBackend::getFixupKindInfo(Kind); | 235 return MCAsmBackend::getFixupKindInfo(Kind); |
197 | 236 |
198 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && | 237 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && |
199 "Invalid kind!"); | 238 "Invalid kind!"); |
200 return Infos[Kind - FirstTargetFixupKind]; | 239 return Infos[Kind - FirstTargetFixupKind]; |
201 } | 240 } |
202 | 241 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
290 // @LOCALMOD-END | 329 // @LOCALMOD-END |
291 return new MipsAsmBackend(T, Triple(TT).getOS(), | 330 return new MipsAsmBackend(T, Triple(TT).getOS(), |
292 /*IsLittle*/true, /*Is64Bit*/true); | 331 /*IsLittle*/true, /*Is64Bit*/true); |
293 } | 332 } |
294 | 333 |
295 MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, StringRef TT, | 334 MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, StringRef TT, |
296 StringRef CPU) { | 335 StringRef CPU) { |
297 return new MipsAsmBackend(T, Triple(TT).getOS(), | 336 return new MipsAsmBackend(T, Triple(TT).getOS(), |
298 /*IsLittle*/false, /*Is64Bit*/true); | 337 /*IsLittle*/false, /*Is64Bit*/true); |
299 } | 338 } |
OLD | NEW |