aboutsummaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@mips.com>2012-03-21 00:52:01 +0000
committerAkira Hatanaka <ahatanaka@mips.com>2012-03-21 00:52:01 +0000
commitfb54afbcb8f460c5c4cafa605259ba0dd77504dc (patch)
tree9f66dcb3d6e76c8410bc21deb2df4d5edc8b7966 /lib/Target
parentb7febfbafae97bce00bd239d34e91b9997a5338d (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.cpp37
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp6
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);
}
}