diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2012-03-21 00:52:01 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2012-03-21 00:52:01 +0000 |
commit | fb54afbcb8f460c5c4cafa605259ba0dd77504dc (patch) | |
tree | 9f66dcb3d6e76c8410bc21deb2df4d5edc8b7966 /lib/Target | |
parent | b7febfbafae97bce00bd239d34e91b9997a5338d (diff) |
Incremental big endian patch by Jack Carter.
These changes allow us to compile big endian from the command line for 32 bit
Mips targets. This patch will result in code and data actually being produced
in the correct endianess.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153153 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 37 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 6 |
2 files changed, 30 insertions, 13 deletions
diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index d69570bdf0..7f5c3775b0 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -92,25 +92,42 @@ public: if (!Value) return; // Doesn't change encoding. + // Where do we start in the object unsigned Offset = Fixup.getOffset(); - // FIXME: The below code will not work across endian models - // How many bytes/bits are we fixing up? - unsigned NumBytes = ((getFixupKindInfo(Kind).TargetSize-1)/8)+1; - uint64_t Mask = ((uint64_t)1 << getFixupKindInfo(Kind).TargetSize) - 1; + // Number of bytes we need to fixup + unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8; + // Used to point to big endian bytes + unsigned FullSize; + + switch (Kind) { + case Mips::fixup_Mips_16: + FullSize = 2; + break; + case Mips::fixup_Mips_64: + FullSize = 8; + break; + default: + FullSize = 4; + break; + } // Grab current value, if any, from bits. uint64_t CurVal = 0; - for (unsigned i = 0; i != NumBytes; ++i) - CurVal |= ((uint8_t)Data[Offset + i]) << (i * 8); + for (unsigned i = 0; i != NumBytes; ++i) { + unsigned Idx = IsLittle ? i : (FullSize - 1 - i); + CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8); + } + + uint64_t Mask = ((uint64_t)(-1) >> (64 - getFixupKindInfo(Kind).TargetSize)); CurVal = (CurVal & ~Mask) | ((CurVal + Value) & Mask); - // Write out the bytes back to the code/data bits. - // First the unaffected bits and then the fixup. + // Write out the fixed up bytes back to the code/data bits. for (unsigned i = 0; i != NumBytes; ++i) { - Data[Offset + i] = uint8_t((CurVal >> (i * 8)) & 0xff); + unsigned Idx = IsLittle ? i : (FullSize - 1 - i); + Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff); } -} + } unsigned getNumFixupKinds() const { return Mips::NumTargetFixupKinds; } diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index b039678175..9ebb6d2569 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -49,9 +49,9 @@ public: void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const { // Output the instruction encoding in little endian byte order. - for (unsigned i = 0; i != Size; ++i) { - EmitByte(Val & 255, OS); - Val >>= 8; + for (unsigned i = 0; i < Size; ++i) { + unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; + EmitByte((Val >> Shift) & 0xff, OS); } } |