]> granicus.if.org Git - llvm/commitdiff
[AArch64] Support the .inst directive for MachO and COFF targets
authorMartin Storsjo <martin@martin.st>
Tue, 31 Jul 2018 09:26:52 +0000 (09:26 +0000)
committerMartin Storsjo <martin@martin.st>
Tue, 31 Jul 2018 09:26:52 +0000 (09:26 +0000)
Contrary to ELF, we don't add any markers that distinguish data generated
with .long from normal instructions, so the .inst directive only adds
compatibility with assembly that uses it.

Differential Revision: https://reviews.llvm.org/D49935

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338355 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
test/MC/AArch64/inst-directive-other.s [new file with mode: 0644]

index 786ee91bb8a5f227e76f87b12241a18b2889c5ef..ee9443b3f71df957a5768a74a8c8c47f7d38c47d 100644 (file)
@@ -4873,12 +4873,11 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
     parseDirectiveLtorg(Loc);
   else if (IDVal == ".unreq")
     parseDirectiveUnreq(Loc);
-  else if (!IsMachO && !IsCOFF) {
-    if (IDVal == ".inst")
-      parseDirectiveInst(Loc);
-    else
-      return true;
-  } else if (IDVal == MCLOHDirectiveName())
+  else if (IDVal == ".inst")
+    parseDirectiveInst(Loc);
+  else if (!IsMachO && !IsCOFF)
+    return true;
+  else if (IDVal == MCLOHDirectiveName())
     parseDirectiveLOH(IDVal, Loc);
   else
     return true;
index 1b949b54590c7e6c340aac608dc14c65860cf1e7..dee964df26356fcc59c71c5358082199cbd6666c 100644 (file)
@@ -39,4 +39,16 @@ void AArch64TargetStreamer::emitCurrentConstantPool() {
 // finish() - write out any non-empty assembler constant pools.
 void AArch64TargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
 
-void AArch64TargetStreamer::emitInst(uint32_t Inst) {}
+void AArch64TargetStreamer::emitInst(uint32_t Inst) {
+  char Buffer[4];
+
+  // We can't just use EmitIntValue here, as that will swap the
+  // endianness on big-endian systems (instructions are always
+  // little-endian).
+  for (unsigned I = 0; I < 4; ++I) {
+    Buffer[I] = uint8_t(Inst);
+    Inst >>= 8;
+  }
+
+  getStreamer().EmitBytes(StringRef(Buffer, 4));
+}
diff --git a/test/MC/AArch64/inst-directive-other.s b/test/MC/AArch64/inst-directive-other.s
new file mode 100644 (file)
index 0000000..02f21c1
--- /dev/null
@@ -0,0 +1,42 @@
+// RUN: llvm-mc %s -triple=arm64-apple-darwin -filetype=asm -o - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ASM
+// RUN: llvm-mc %s -triple=arm64-apple-darwin -filetype=obj -o - \
+// RUN:   | llvm-objdump -d - | FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-CODE
+// RUN: llvm-mc %s -triple=aarch64-win32-gnu -filetype=asm -o - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ASM
+// RUN: llvm-mc %s -triple=aarch64-win32-gnu -filetype=obj -o - \
+// RUN:   | llvm-objdump -d - | FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-CODE
+// RUN: llvm-mc %s -triple=aarch64-linux-gnu -filetype=asm -o - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ASM
+// RUN: llvm-mc %s -triple=aarch64-linux-gnu -filetype=obj -o - \
+// RUN:   | llvm-objdump -d - | FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-DATA
+// RUN: llvm-mc %s -triple=aarch64_be-linux-gnu -filetype=asm -o - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ASM
+// RUN: llvm-mc %s -triple=aarch64_be-linux-gnu -filetype=obj -o - \
+// RUN:   | llvm-objdump -d - | FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-BE
+
+    .text
+
+    .p2align  2
+    .globl _func
+_func:
+    nop
+    // A .long is stored differently for big endian aarch64 targets, while
+    // instructions always are stored in little endian.
+    // ELF distinguishes between data and code when emitted this way, but
+    // MachO and COFF don't.
+    .long 0xd503201f
+    .inst 0xd503201f
+
+// CHECK-ASM:        .p2align  2
+// CHECK-ASM:        .globl  _func
+// CHECK-ASM: _func:
+// CHECK-ASM:        nop
+// CHECK-ASM:        .{{long|word}}   3573751839
+// CHECK-ASM:        .inst   0xd503201f
+
+// CHECK-OBJ:        0:       1f 20 03 d5     nop
+// CHECK-OBJ-CODE:   4:       1f 20 03 d5     nop
+// CHECK-OBJ-DATA:   4:       1f 20 03 d5     .word 0xd503201f
+// CHECK-OBJ-BE:     4:       d5 03 20 1f     .word 0xd503201f
+// CHECK-OBJ:        8:       1f 20 03 d5     nop