diff options
author | Zoran Jovanovic <zoran.jovanovic@imgtec.com> | 2014-04-03 12:01:01 +0000 |
---|---|---|
committer | Zoran Jovanovic <zoran.jovanovic@imgtec.com> | 2014-04-03 12:01:01 +0000 |
commit | 60f5dfea66f8ad2a3fffe559567ff8dd7c382898 (patch) | |
tree | fdd03da0c662f7b676dce358a9ddf902a45b8c1b | |
parent | badb1377291e99cea122b64ee62fa0382e9ee737 (diff) | |
download | llvm-60f5dfea66f8ad2a3fffe559567ff8dd7c382898.tar.gz llvm-60f5dfea66f8ad2a3fffe559567ff8dd7c382898.tar.bz2 llvm-60f5dfea66f8ad2a3fffe559567ff8dd7c382898.tar.xz |
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
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 26 | ||||
-rw-r--r-- | test/MC/Mips/micromips-el-fixup-data.s | 25 |
2 files changed, 49 insertions, 2 deletions
diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 541f8b6f91..0f99ecc548 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -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); } } diff --git a/test/MC/Mips/micromips-el-fixup-data.s b/test/MC/Mips/micromips-el-fixup-data.s new file mode 100644 index 0000000000..2293f63d46 --- /dev/null +++ b/test/MC/Mips/micromips-el-fixup-data.s @@ -0,0 +1,25 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 \ +# RUN: -mattr=+micromips 2>&1 -filetype=obj > %t.o +# RUN: llvm-objdump %t.o -triple mipsel -mattr=+micromips -d | FileCheck %s + +# Check that fixup data is writen in the microMIPS specific little endian +# byte order. + + .text + .globl main + .align 2 + .type main,@function + .set micromips + .set nomips16 + .ent main +main: + addiu $sp, $sp, -16 + bnez $9, lab1 + +# CHECK: 09 b4 04 00 bne $9, $zero, 8 + + addu $zero, $zero, $zero +lab1: + jr $ra + addiu $sp, $sp, 16 + .end main |