From 90e3e8259bc57e338c4748eabda85852a39109ce 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338355 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AArch64/AsmParser/AArch64AsmParser.cpp | 11 +++-- .../MCTargetDesc/AArch64TargetStreamer.cpp | 14 ++++++- test/MC/AArch64/inst-directive-other.s | 42 +++++++++++++++++++ 3 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 test/MC/AArch64/inst-directive-other.s diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 786ee91bb8a..ee9443b3f71 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/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/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp index 1b949b54590..dee964df263 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp +++ b/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/test/MC/AArch64/inst-directive-other.s b/test/MC/AArch64/inst-directive-other.s new file mode 100644 index 00000000000..02f21c13d29 --- /dev/null +++ b/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 -- 2.50.1