MicroMIPS specific little endian fixup data byte ordering.

Differential Revision: http://llvm-reviews.chandlerc.com/D3245


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205528 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zoran Jovanovic
2014-04-03 12:01:01 +00:00
parent badb137729
commit 60f5dfea66
2 changed files with 49 additions and 2 deletions

View File

@@ -112,6 +112,22 @@ MCObjectWriter *MipsAsmBackend::createObjectWriter(raw_ostream &OS) const {
MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit);
}
// Little-endian fixup data byte ordering:
// mips32r2: a | b | x | x
// microMIPS: x | x | a | b
static bool needsMMLEByteOrder(unsigned Kind) {
return Kind >= Mips::fixup_MICROMIPS_26_S1 &&
Kind < Mips::LastTargetFixupKind;
}
// Calculate index for microMIPS specific little endian byte order
static unsigned calculateMMLEIndex(unsigned i) {
assert(i <= 3 && "Index out of range!");
return (1 - i / 2) * 2 + i % 2;
}
/// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
@@ -149,8 +165,12 @@ void MipsAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
// Grab current value, if any, from bits.
uint64_t CurVal = 0;
bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
for (unsigned i = 0; i != NumBytes; ++i) {
unsigned Idx = IsLittle ? i : (FullSize - 1 - i);
unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
: i)
: (FullSize - 1 - i);
CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
}
@@ -160,7 +180,9 @@ void MipsAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
// Write out the fixed up bytes back to the code/data bits.
for (unsigned i = 0; i != NumBytes; ++i) {
unsigned Idx = IsLittle ? i : (FullSize - 1 - i);
unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
: i)
: (FullSize - 1 - i);
Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
}
}