summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-04-15 14:00:15 +0000
committerTim Northover <tnorthover@apple.com>2014-04-15 14:00:15 +0000
commit2a83cb71ad74988d834c8969ca34027fce251a12 (patch)
treea9f56ef53a46b2da0504a8fade825a9fc633a4bc
parent5080ae2e21945f3f50a4a0440f833022ab3b15ba (diff)
downloadllvm-2a83cb71ad74988d834c8969ca34027fce251a12.tar.gz
llvm-2a83cb71ad74988d834c8969ca34027fce251a12.tar.bz2
llvm-2a83cb71ad74988d834c8969ca34027fce251a12.tar.xz
AArch64/ARM64: only mangle MOVZ/MOVN during encoding when needed
Sometimes we need emit the bits that would actually be a MOVN when producing a relocated MOVZ instruction (don't ask). But not always, a check which ARM64 got wrong until now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206289 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp16
-rw-r--r--test/CodeGen/AArch64/large-consts.ll16
-rw-r--r--test/MC/ARM64/large-relocs.s8
3 files changed, 31 insertions, 9 deletions
diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp b/lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp
index 95020e4395..f65099e85b 100644
--- a/lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp
+++ b/lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp
@@ -550,6 +550,22 @@ unsigned ARM64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
if (UImm16MO.isImm())
return EncodedValue;
+ const ARM64MCExpr *A64E = cast<ARM64MCExpr>(UImm16MO.getExpr());
+ switch (A64E->getKind()) {
+ case ARM64MCExpr::VK_DTPREL_G2:
+ case ARM64MCExpr::VK_DTPREL_G1:
+ case ARM64MCExpr::VK_DTPREL_G0:
+ case ARM64MCExpr::VK_GOTTPREL_G1:
+ case ARM64MCExpr::VK_TPREL_G2:
+ case ARM64MCExpr::VK_TPREL_G1:
+ case ARM64MCExpr::VK_TPREL_G0:
+ return EncodedValue & ~(1u << 30);
+ default:
+ // Nothing to do for an unsigned fixup.
+ return EncodedValue;
+ }
+
+
return EncodedValue & ~(1u << 30);
}
diff --git a/test/CodeGen/AArch64/large-consts.ll b/test/CodeGen/AArch64/large-consts.ll
index 1b769c6e35..b1f98b9cf9 100644
--- a/test/CodeGen/AArch64/large-consts.ll
+++ b/test/CodeGen/AArch64/large-consts.ll
@@ -1,13 +1,19 @@
-; RUN: llc -mtriple=aarch64-linux-gnu -o - %s -code-model=large -show-mc-encoding | FileCheck %s
+; RUN: llc -mtriple=aarch64-linux-gnu -o - %s -code-model=large -show-mc-encoding | FileCheck %s --check-prefix=CHECK-AARCH64
+; RUN: llc -mtriple=arm64-linux-gnu -o - %s -code-model=large -show-mc-encoding | FileCheck %s --check-prefix=CHECK-ARM64
; Make sure the shift amount is encoded into the instructions by LLVM because
; it's not the linker's job to put it there.
define double @foo() {
-; CHECK: movz [[CPADDR:x[0-9]+]], #:abs_g3:.LCPI0_0 // encoding: [A,A,0xe0'A',0xd2'A']
-; CHECK: movk [[CPADDR]], #:abs_g2_nc:.LCPI0_0 // encoding: [A,A,0xc0'A',0xf2'A']
-; CHECK: movk [[CPADDR]], #:abs_g1_nc:.LCPI0_0 // encoding: [A,A,0xa0'A',0xf2'A']
-; CHECK: movk [[CPADDR]], #:abs_g0_nc:.LCPI0_0 // encoding: [A,A,0x80'A',0xf2'A']
+; CHECK-AARCH64: movz [[CPADDR:x[0-9]+]], #:abs_g3:.LCPI0_0 // encoding: [A,A,0xe0'A',0xd2'A']
+; CHECK-AARCH64: movk [[CPADDR]], #:abs_g2_nc:.LCPI0_0 // encoding: [A,A,0xc0'A',0xf2'A']
+; CHECK-AARCH64: movk [[CPADDR]], #:abs_g1_nc:.LCPI0_0 // encoding: [A,A,0xa0'A',0xf2'A']
+; CHECK-AARCH64: movk [[CPADDR]], #:abs_g0_nc:.LCPI0_0 // encoding: [A,A,0x80'A',0xf2'A']
+
+; CHECK-ARM64: movz [[CPADDR:x[0-9]+]], #:abs_g3:.LCPI0_0 // encoding: [0bAAA01000,A,0b111AAAAA,0xd2]
+; CHECK-ARM64: movk [[CPADDR]], #:abs_g2_nc:.LCPI0_0 // encoding: [0bAAA01000,A,0b110AAAAA,0xf2]
+; CHECK-ARM64: movk [[CPADDR]], #:abs_g1_nc:.LCPI0_0 // encoding: [0bAAA01000,A,0b101AAAAA,0xf2]
+; CHECK-ARM64: movk [[CPADDR]], #:abs_g0_nc:.LCPI0_0 // encoding: [0bAAA01000,A,0b100AAAAA,0xf2]
ret double 3.14159
}
diff --git a/test/MC/ARM64/large-relocs.s b/test/MC/ARM64/large-relocs.s
index 348ceb6db5..48aea43d6b 100644
--- a/test/MC/ARM64/large-relocs.s
+++ b/test/MC/ARM64/large-relocs.s
@@ -3,7 +3,7 @@
movz x2, #:abs_g0:sym
movk w3, #:abs_g0_nc:sym
-// CHECK: movz x2, #:abs_g0:sym // encoding: [0bAAA00010,A,0b100AAAAA,0x92]
+// CHECK: movz x2, #:abs_g0:sym // encoding: [0bAAA00010,A,0b100AAAAA,0xd2]
// CHECK-NEXT: // fixup A - offset: 0, value: :abs_g0:sym, kind: fixup_arm64_movw
// CHECK: movk w3, #:abs_g0_nc:sym // encoding: [0bAAA00011,A,0b100AAAAA,0x72]
// CHECK-NEXT: // fixup A - offset: 0, value: :abs_g0_nc:sym, kind: fixup_arm64_movw
@@ -13,7 +13,7 @@
movz x4, #:abs_g1:sym
movk w5, #:abs_g1_nc:sym
-// CHECK: movz x4, #:abs_g1:sym // encoding: [0bAAA00100,A,0b101AAAAA,0x92]
+// CHECK: movz x4, #:abs_g1:sym // encoding: [0bAAA00100,A,0b101AAAAA,0xd2]
// CHECK-NEXT: // fixup A - offset: 0, value: :abs_g1:sym, kind: fixup_arm64_movw
// CHECK: movk w5, #:abs_g1_nc:sym // encoding: [0bAAA00101,A,0b101AAAAA,0x72]
// CHECK-NEXT: // fixup A - offset: 0, value: :abs_g1_nc:sym, kind: fixup_arm64_movw
@@ -23,7 +23,7 @@
movz x6, #:abs_g2:sym
movk x7, #:abs_g2_nc:sym
-// CHECK: movz x6, #:abs_g2:sym // encoding: [0bAAA00110,A,0b110AAAAA,0x92]
+// CHECK: movz x6, #:abs_g2:sym // encoding: [0bAAA00110,A,0b110AAAAA,0xd2]
// CHECK-NEXT: // fixup A - offset: 0, value: :abs_g2:sym, kind: fixup_arm64_movw
// CHECK: movk x7, #:abs_g2_nc:sym // encoding: [0bAAA00111,A,0b110AAAAA,0xf2]
// CHECK-NEXT: // fixup A - offset: 0, value: :abs_g2_nc:sym, kind: fixup_arm64_movw
@@ -32,7 +32,7 @@
// CHECK-OBJ: 14 R_AARCH64_MOVW_UABS_G2_NC sym
movz x8, #:abs_g3:sym
-// CHECK: movz x8, #:abs_g3:sym // encoding: [0bAAA01000,A,0b111AAAAA,0x92]
+// CHECK: movz x8, #:abs_g3:sym // encoding: [0bAAA01000,A,0b111AAAAA,0xd2]
// CHECK-NEXT: // fixup A - offset: 0, value: :abs_g3:sym, kind: fixup_arm64_movw
// CHECK-OBJ: 18 R_AARCH64_MOVW_UABS_G3 sym