Skip to content

Commit

Permalink
[AArch64] Support the .inst directive for MachO and COFF targets
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mstorsjo committed Jul 31, 2018
1 parent 2a6c842 commit 3e3d39d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 7 deletions.
11 changes: 5 additions & 6 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 13 additions & 1 deletion llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
42 changes: 42 additions & 0 deletions llvm/test/MC/AArch64/inst-directive-other.s
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 3e3d39d

Please sign in to comment.