From b3fa233048eb74109d0274bda43e3a829950d4e8 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 23 May 2014 13:35:24 +0000 Subject: [PATCH] [mips] Work around inconsistency in llvm-mc's placement of fixup markers Summary: Add a second fixup table to MipsAsmBackend::getFixupKindInfo() to correctly position llvm-mc's fixup placeholders for big-endian. See PR19836 for full details of the issue. To summarize, the fixup placeholders do not account for endianness properly and the implementations of getFixupKindInfo() for each target are measuring MCFixupKindInfo.TargetOffset from different ends of the instruction encoding to compensate. Reviewers: jkolek, zoran.jovanovic, vmedic Reviewed By: vmedic Differential Revision: http://reviews.llvm.org/D3889 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209514 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/MCTargetDesc/MipsAsmBackend.cpp | 64 ++++++++++++++++++- test/MC/Mips/llvm-mc-fixup-endianness.s | 6 ++ test/MC/Mips/mips_directives.s | 2 +- test/MC/Mips/mips_gprel16.s | 3 + test/MC/Mips/msa/test_cbranch.s | 20 +++--- 5 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 test/MC/Mips/llvm-mc-fixup-endianness.s diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 153974e470f..332f7ea7a26 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -189,7 +189,7 @@ void MipsAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, const MCFixupKindInfo &MipsAsmBackend:: getFixupKindInfo(MCFixupKind Kind) const { - const static MCFixupKindInfo Infos[Mips::NumTargetFixupKinds] = { + const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = { // This table *must* be in same the order of fixup_* kinds in // MipsFixupKinds.h. // @@ -246,12 +246,72 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 } }; + const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = { + // This table *must* be in same the order of fixup_* kinds in + // MipsFixupKinds.h. + // + // name offset bits flags + { "fixup_Mips_16", 16, 16, 0 }, + { "fixup_Mips_32", 0, 32, 0 }, + { "fixup_Mips_REL32", 0, 32, 0 }, + { "fixup_Mips_26", 6, 26, 0 }, + { "fixup_Mips_HI16", 16, 16, 0 }, + { "fixup_Mips_LO16", 16, 16, 0 }, + { "fixup_Mips_GPREL16", 16, 16, 0 }, + { "fixup_Mips_LITERAL", 16, 16, 0 }, + { "fixup_Mips_GOT_Global", 16, 16, 0 }, + { "fixup_Mips_GOT_Local", 16, 16, 0 }, + { "fixup_Mips_PC16", 16, 16, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_Mips_CALL16", 16, 16, 0 }, + { "fixup_Mips_GPREL32", 0, 32, 0 }, + { "fixup_Mips_SHIFT5", 21, 5, 0 }, + { "fixup_Mips_SHIFT6", 21, 5, 0 }, + { "fixup_Mips_64", 0, 64, 0 }, + { "fixup_Mips_TLSGD", 16, 16, 0 }, + { "fixup_Mips_GOTTPREL", 16, 16, 0 }, + { "fixup_Mips_TPREL_HI", 16, 16, 0 }, + { "fixup_Mips_TPREL_LO", 16, 16, 0 }, + { "fixup_Mips_TLSLDM", 16, 16, 0 }, + { "fixup_Mips_DTPREL_HI", 16, 16, 0 }, + { "fixup_Mips_DTPREL_LO", 16, 16, 0 }, + { "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_Mips_GPOFF_HI", 16, 16, 0 }, + { "fixup_Mips_GPOFF_LO", 16, 16, 0 }, + { "fixup_Mips_GOT_PAGE", 16, 16, 0 }, + { "fixup_Mips_GOT_OFST", 16, 16, 0 }, + { "fixup_Mips_GOT_DISP", 16, 16, 0 }, + { "fixup_Mips_HIGHER", 16, 16, 0 }, + { "fixup_Mips_HIGHEST", 16, 16, 0 }, + { "fixup_Mips_GOT_HI16", 16, 16, 0 }, + { "fixup_Mips_GOT_LO16", 16, 16, 0 }, + { "fixup_Mips_CALL_HI16", 16, 16, 0 }, + { "fixup_Mips_CALL_LO16", 16, 16, 0 }, + { "fixup_MICROMIPS_26_S1", 6, 26, 0 }, + { "fixup_MICROMIPS_HI16", 16, 16, 0 }, + { "fixup_MICROMIPS_LO16", 16, 16, 0 }, + { "fixup_MICROMIPS_GOT16", 16, 16, 0 }, + { "fixup_MICROMIPS_PC16_S1",16, 16, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_MICROMIPS_CALL16", 16, 16, 0 }, + { "fixup_MICROMIPS_GOT_DISP", 16, 16, 0 }, + { "fixup_MICROMIPS_GOT_PAGE", 16, 16, 0 }, + { "fixup_MICROMIPS_GOT_OFST", 16, 16, 0 }, + { "fixup_MICROMIPS_TLS_GD", 16, 16, 0 }, + { "fixup_MICROMIPS_TLS_LDM", 16, 16, 0 }, + { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16, 16, 0 }, + { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16, 16, 0 }, + { "fixup_MICROMIPS_TLS_TPREL_HI16", 16, 16, 0 }, + { "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 } + }; + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); - return Infos[Kind - FirstTargetFixupKind]; + + if (IsLittle) + return LittleEndianInfos[Kind - FirstTargetFixupKind]; + return BigEndianInfos[Kind - FirstTargetFixupKind]; } /// WriteNopData - Write an (optimal) nop sequence of Count bytes diff --git a/test/MC/Mips/llvm-mc-fixup-endianness.s b/test/MC/Mips/llvm-mc-fixup-endianness.s new file mode 100644 index 00000000000..bc6a5d96632 --- /dev/null +++ b/test/MC/Mips/llvm-mc-fixup-endianness.s @@ -0,0 +1,6 @@ +# RUN: llvm-mc -show-encoding -mcpu=mips32 -triple mips-unknown-unknown %s | FileCheck -check-prefix=BE %s +# RUN: llvm-mc -show-encoding -mcpu=mips32 -triple mipsel-unknown-unknown %s | FileCheck -check-prefix=LE %s +# + .text + b foo # BE: b foo # encoding: [0x10,0x00,A,A] + # LE: b foo # encoding: [A,A,0x00,0x10] diff --git a/test/MC/Mips/mips_directives.s b/test/MC/Mips/mips_directives.s index 6780dd0b3ca..1a7d61f3ad4 100644 --- a/test/MC/Mips/mips_directives.s +++ b/test/MC/Mips/mips_directives.s @@ -51,7 +51,7 @@ $BB0_4: .set $tmp7, $BB0_4-$BB0_2 .set f6,$f6 # CHECK: abs.s $f6, $f7 # encoding: [0x46,0x00,0x39,0x85] -# CHECK: lui $1, %hi($tmp7) # encoding: [0x3c'A',0x01'A',0x00,0x00] +# CHECK: lui $1, %hi($tmp7) # encoding: [0x3c,0x01,A,A] # CHECK: # fixup A - offset: 0, value: ($tmp7)@ABS_HI, kind: fixup_Mips_HI16 abs.s f6,FPU_MASK lui $1, %hi($tmp7) diff --git a/test/MC/Mips/mips_gprel16.s b/test/MC/Mips/mips_gprel16.s index 716c75ec88d..9dd3fa3281c 100644 --- a/test/MC/Mips/mips_gprel16.s +++ b/test/MC/Mips/mips_gprel16.s @@ -5,6 +5,9 @@ // RUN: llvm-mc -mcpu=mips32r2 -triple=mipsel-pc-linux -filetype=obj -relocation-model=static %s -o - \ // RUN: | llvm-objdump -disassemble -mattr +mips32r2 - \ +// RUN: | FileCheck %s +// RUN: llvm-mc -mcpu=mips32r2 -triple=mips-pc-linux -filetype=obj -relocation-model=static %s -o - \ +// RUN: | llvm-objdump -disassemble -mattr +mips32r2 - \ // RUN: | FileCheck %s .text diff --git a/test/MC/Mips/msa/test_cbranch.s b/test/MC/Mips/msa/test_cbranch.s index 37b88725602..aa6779b1b46 100644 --- a/test/MC/Mips/msa/test_cbranch.s +++ b/test/MC/Mips/msa/test_cbranch.s @@ -7,22 +7,22 @@ #CHECK: bnz.w $w2, 128 # encoding: [0x47,0xc2,0x00,0x20] #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] #CHECK: bnz.d $w3, -128 # encoding: [0x47,0xe3,0xff,0xe0] -#CHECK: bnz.b $w0, SYMBOL0 # encoding: [0x47'A',0x80'A',0x00,0x00] +#CHECK: bnz.b $w0, SYMBOL0 # encoding: [0x47,0x80,A,A] # fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bnz.h $w1, SYMBOL1 # encoding: [0x47'A',0xa1'A',0x00,0x00] +#CHECK: bnz.h $w1, SYMBOL1 # encoding: [0x47,0xa1,A,A] # fixup A - offset: 0, value: SYMBOL1, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bnz.w $w2, SYMBOL2 # encoding: [0x47'A',0xc2'A',0x00,0x00] +#CHECK: bnz.w $w2, SYMBOL2 # encoding: [0x47,0xc2,A,A] # fixup A - offset: 0, value: SYMBOL2, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bnz.d $w3, SYMBOL3 # encoding: [0x47'A',0xe3'A',0x00,0x00] +#CHECK: bnz.d $w3, SYMBOL3 # encoding: [0x47,0xe3,A,A] # fixup A - offset: 0, value: SYMBOL3, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] #CHECK: bnz.v $w0, 4 # encoding: [0x45,0xe0,0x00,0x01] #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bnz.v $w0, SYMBOL0 # encoding: [0x45'A',0xe0'A',0x00,0x00] +#CHECK: bnz.v $w0, SYMBOL0 # encoding: [0x45,0xe0,A,A] # fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] @@ -34,22 +34,22 @@ #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] #CHECK: bz.d $w3, -1024 # encoding: [0x47,0x63,0xff,0x00] #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bz.b $w0, SYMBOL0 # encoding: [0x47'A',A,0x00,0x00] +#CHECK: bz.b $w0, SYMBOL0 # encoding: [0x47,0x00,A,A] # fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bz.h $w1, SYMBOL1 # encoding: [0x47'A',0x21'A',0x00,0x00] +#CHECK: bz.h $w1, SYMBOL1 # encoding: [0x47,0x21,A,A] # fixup A - offset: 0, value: SYMBOL1, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bz.w $w2, SYMBOL2 # encoding: [0x47'A',0x42'A',0x00,0x00] +#CHECK: bz.w $w2, SYMBOL2 # encoding: [0x47,0x42,A,A] # fixup A - offset: 0, value: SYMBOL2, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bz.d $w3, SYMBOL3 # encoding: [0x47'A',0x63'A',0x00,0x00] +#CHECK: bz.d $w3, SYMBOL3 # encoding: [0x47,0x63,A,A] # fixup A - offset: 0, value: SYMBOL3, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] #CHECK: bz.v $w0, 4 # encoding: [0x45,0x60,0x00,0x01] #CHECK: nop # encoding: [0x00,0x00,0x00,0x00] -#CHECK: bz.v $w0, SYMBOL0 # encoding: [0x45'A',0x60'A',0x00,0x00] +#CHECK: bz.v $w0, SYMBOL0 # encoding: [0x45,0x60,A,A] # fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16 #CHECK: nop # encoding: [0x00,0x00,0x00,0x00]