- // Check whether we need to relax this fixup.
- if (!FixupNeedsRelaxation(Fixup, DF, Layout))
- continue;
-
- // Relax the instruction.
- //
- // FIXME: This is a huge temporary hack which just looks for x86
- // branches; the only thing we need to relax on x86 is
- // 'X86::reloc_pcrel_1byte'. Once we have MCInst fragments, this will be
- // replaced by a TargetAsmBackend hook (most likely tblgen'd) to relax
- // an individual MCInst.
- SmallVectorImpl<char> &C = DF->getContents();
- uint64_t PrevOffset = Fixup.Offset;
- unsigned Amt = 0;
-
- // jcc instructions
- if (unsigned(C[Fixup.Offset-1]) >= 0x70 &&
- unsigned(C[Fixup.Offset-1]) <= 0x7f) {
- C[Fixup.Offset] = C[Fixup.Offset-1] + 0x10;
- C[Fixup.Offset-1] = char(0x0f);
- ++Fixup.Offset;
- Amt = 4;
-
- // jmp rel8
- } else if (C[Fixup.Offset-1] == char(0xeb)) {
- C[Fixup.Offset-1] = char(0xe9);
- Amt = 3;
-
- } else
- llvm_unreachable("unknown 1 byte pcrel instruction!");
-
- Fixup.Value = MCBinaryExpr::Create(
- MCBinaryExpr::Sub, Fixup.Value,
- MCConstantExpr::Create(3, getContext()),
- getContext());
- C.insert(C.begin() + Fixup.Offset, Amt, char(0));
- Fixup.Kind = MCFixupKind(X86::reloc_pcrel_4byte);
-
- // Update the remaining fixups, which have slid.
- //
- // FIXME: This is bad for performance, but will be eliminated by the
- // move to MCInst specific fragments.
- ++it3;
- for (; it3 != ie3; ++it3)
- it3->Offset += Amt;
-
- // Update all the symbols for this fragment, which may have slid.
- //
- // FIXME: This is really really bad for performance, but will be
- // eliminated by the move to MCInst specific fragments.
- for (MCAssembler::symbol_iterator it = symbol_begin(),
- ie = symbol_end(); it != ie; ++it) {
- MCSymbolData &SD = *it;
-
- if (it->getFragment() != DF)
- continue;
-
- if (SD.getOffset() > PrevOffset)
- SD.setOffset(SD.getOffset() + Amt);
- }