llvm.org GIT mirror llvm / 4c60168
[ARM] Support the .inst directive for MachO and COFF targets Contrary to ELF, we don't add any markers that distinguish data generated with .short/.long from normal instructions, so the .inst directive only adds compatibility with assembly that uses it. Differential Revision: https://reviews.llvm.org/D49936 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338356 91177308-0d34-0410-b5e6-96231b3b80d8 Martin Storsjo 2 years ago
4 changed file(s) with 90 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
93709370 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
93719371 else if (IDVal == ".thumb_set")
93729372 parseDirectiveThumbSet(DirectiveID.getLoc());
9373 else if (IDVal == ".inst")
9374 parseDirectiveInst(DirectiveID.getLoc());
9375 else if (IDVal == ".inst.n")
9376 parseDirectiveInst(DirectiveID.getLoc(), 'n');
9377 else if (IDVal == ".inst.w")
9378 parseDirectiveInst(DirectiveID.getLoc(), 'w');
93739379 else if (!IsMachO && !IsCOFF) {
93749380 if (IDVal == ".arch")
93759381 parseDirectiveArch(DirectiveID.getLoc());
93819387 parseDirectiveFPU(DirectiveID.getLoc());
93829388 else if (IDVal == ".fnstart")
93839389 parseDirectiveFnStart(DirectiveID.getLoc());
9384 else if (IDVal == ".inst")
9385 parseDirectiveInst(DirectiveID.getLoc());
9386 else if (IDVal == ".inst.n")
9387 parseDirectiveInst(DirectiveID.getLoc(), 'n');
9388 else if (IDVal == ".inst.w")
9389 parseDirectiveInst(DirectiveID.getLoc(), 'w');
93909390 else if (IDVal == ".object_arch")
93919391 parseDirectiveObjectArch(DirectiveID.getLoc());
93929392 else if (IDVal == ".tlsdescseq")
1212
1313 #include "ARMTargetMachine.h"
1414 #include "llvm/MC/ConstantPools.h"
15 #include "llvm/MC/MCAsmInfo.h"
16 #include "llvm/MC/MCContext.h"
1517 #include "llvm/MC/MCExpr.h"
1618 #include "llvm/MC/MCStreamer.h"
1719 #include "llvm/MC/MCSubtargetInfo.h"
4547
4648 // reset() - Reset any state
4749 void ARMTargetStreamer::reset() {}
50
51 void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {
52 unsigned Size;
53 char Buffer[4];
54 const bool LittleEndian = getStreamer().getContext().getAsmInfo()->isLittleEndian();
55
56 switch (Suffix) {
57 case '\0':
58 Size = 4;
59
60 for (unsigned II = 0, IE = Size; II != IE; II++) {
61 const unsigned I = LittleEndian ? (Size - II - 1) : II;
62 Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
63 }
64
65 break;
66 case 'n':
67 case 'w':
68 Size = (Suffix == 'n' ? 2 : 4);
69
70 // Thumb wide instructions are emitted as a pair of 16-bit words of the
71 // appropriate endianness.
72 for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
73 const unsigned I0 = LittleEndian ? II + 0 : II + 1;
74 const unsigned I1 = LittleEndian ? II + 1 : II + 0;
75 Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
76 Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
77 }
78
79 break;
80 default:
81 llvm_unreachable("Invalid Suffix");
82 }
83 getStreamer().EmitBytes(StringRef(Buffer, Size));
84 }
4885
4986 // The remaining callbacks should be handled separately by each
5087 // streamer.
75112 void ARMTargetStreamer::emitObjectArch(ARM::ArchKind Arch) {}
76113 void ARMTargetStreamer::emitFPU(unsigned FPU) {}
77114 void ARMTargetStreamer::finishAttributeSection() {}
78 void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {}
79115 void
80116 ARMTargetStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) {}
81117 void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {}
2929 // CHECK: .eabi_attribute 0, 0
3030 // CHECK: ^
3131
32 .inst 0xdefe
33
34 // CHECK: error: unknown directive
35 // CHECK: .inst 0xdefe
36 // CHECK: ^
37
38 .inst.n 0xdefe
39
40 // CHECK: error: unknown directive
41 // CHECK: .inst.n 0xdefe
42 // CHECK: ^
43
44 .inst.w 0xdefe
45
46 // CHECK: error: unknown directive
47 // CHECK: .inst.w 0xdefe
48 // CHECK: ^
49
5032 .object_arch armv7
5133
5234 // CHECK: error: unknown directive
0 // RUN: llvm-mc %s -triple=armv7-apple-darwin -filetype=asm -o - \
1 // RUN: | FileCheck %s --check-prefix=CHECK-ASM
2 // RUN: llvm-mc %s -triple=armv7-apple-darwin -filetype=obj -o - \
3 // RUN: | llvm-objdump -triple=thumbv7 -d - | FileCheck %s --check-prefixes=CHECK-OBJ-CODE
4 // RUN: llvm-mc %s -triple=thumbv7-win32-gnu -filetype=asm -o - \
5 // RUN: | FileCheck %s --check-prefix=CHECK-ASM
6 // RUN: llvm-mc %s -triple=thumbv7-win32-gnu -filetype=obj -o - \
7 // RUN: | llvm-objdump -d - | FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-CODE
8 // RUN: llvm-mc %s -triple=armv7-linux-gnueabi -filetype=asm -o - \
9 // RUN: | FileCheck %s --check-prefix=CHECK-ASM
10 // RUN: llvm-mc %s -triple=armv7-linux-gnueabi -filetype=obj -o - \
11 // RUN: | llvm-objdump -d -triple=thumbv7 - | FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-DATA
12
13 .text
14
15 .p2align 2
16 .globl _func
17 .thumb
18 _func:
19 // ELF distinguishes between data and code when emitted this way, but
20 // MachO and COFF don't.
21 bx lr
22 .short 0x4770
23 .inst.n 0x4770
24 mov.w r0, #42
25 .short 0xf04f, 0x002a
26 .inst.w 0xf04f002a
27
28 // CHECK-ASM: .p2align 2
29 // CHECK-ASM: .globl _func
30 // CHECK-ASM: _func:
31 // CHECK-ASM: bx lr
32 // CHECK-ASM: .short 18288
33 // CHECK-ASM: .inst.n 0x4770
34 // CHECK-ASM: mov.w r0, #42
35 // CHECK-ASM: .short 61519
36 // CHECK-ASM: .short 42
37 // CHECK-ASM: .inst.w 0xf04f002a
38
39 // CHECK-OBJ: 0: 70 47 bx lr
40 // CHECK-OBJ-CODE: 2: 70 47 bx lr
41 // CHECK-OBJ-DATA: 2: 70 47 .short 0x4770
42 // CHECK-OBJ: 4: 70 47 bx lr
43 // CHECK-OBJ: 6: 4f f0 2a 00 mov.w r0, #42
44 // CHECK-OBJ-CODE: a: 4f f0 2a 00 mov.w r0, #42
45 // CHECK-OBJ-DATA: a: 4f f0 2a 00 .word 0x002af04f
46 // CHECK-OBJ: e: 4f f0 2a 00 mov.w r0, #42