From 3e3d39d07ea8bc210dfb256edc0ac5c66fb84474 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Tue, 31 Jul 2018 09:26:52 +0000 Subject: [PATCH] [AArch64] Support the .inst directive for MachO and COFF targets 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 llvm-svn: 338355 --- .../AArch64/AsmParser/AArch64AsmParser.cpp | 11 +++-- .../MCTargetDesc/AArch64TargetStreamer.cpp | 14 ++++++- llvm/test/MC/AArch64/inst-directive-other.s | 42 +++++++++++++++++++ 3 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 llvm/test/MC/AArch64/inst-directive-other.s diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 786ee91bb8a5f2..ee9443b3f71df9 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -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; diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp index 1b949b54590c7e..dee964df26356f 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp @@ -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/llvm/test/MC/AArch64/inst-directive-other.s b/llvm/test/MC/AArch64/inst-directive-other.s new file mode 100644 index 00000000000000..02f21c13d2959e --- /dev/null +++ b/llvm/test/MC/AArch64/inst-directive-other.s @@ -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