Make ARM-specific version of getInlineAsmLength
[oota-llvm.git] / lib / Target / ARM / ARMTargetAsmInfo.cpp
1 //===-- ARMTargetAsmInfo.cpp - ARM asm properties ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by James M. Laskey and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the declarations of the ARMTargetAsmInfo properties.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARMTargetAsmInfo.h"
15 #include "ARMTargetMachine.h"
16 #include <cstring>
17 #include <cctype>
18 using namespace llvm;
19
20 ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
21   const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
22   if (Subtarget->isTargetDarwin()) {
23     GlobalPrefix = "_";
24     PrivateGlobalPrefix = "L";
25     BSSSection = 0;                       // no BSS section.
26     ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill
27     SetDirective = "\t.set";
28     WeakRefDirective = "\t.weak_reference\t";
29     HiddenDirective = "\t.private_extern\t";
30     JumpTableDataSection = ".const";
31     CStringSection = "\t.cstring";
32     FourByteConstantSection = "\t.literal4\n";
33     EightByteConstantSection = "\t.literal8\n";
34     ReadOnlySection = "\t.const\n";
35     HasDotTypeDotSizeDirective = false;
36     if (TM.getRelocationModel() == Reloc::Static) {
37       StaticCtorsSection = ".constructor";
38       StaticDtorsSection = ".destructor";
39     } else {
40       StaticCtorsSection = ".mod_init_func";
41       StaticDtorsSection = ".mod_term_func";
42     }
43     
44     // In non-PIC modes, emit a special label before jump tables so that the
45     // linker can perform more accurate dead code stripping.
46     if (TM.getRelocationModel() != Reloc::PIC_) {
47       // Emit a local label that is preserved until the linker runs.
48       JumpTableSpecialLabelPrefix = "l";
49     }
50     
51     NeedsSet = true;
52     DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
53     DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
54     DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
55     DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
56     DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
57     DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
58     DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
59     DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
60     DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
61     DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
62     DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
63   } else {
64     PrivateGlobalPrefix = ".L";
65     WeakRefDirective = "\t.weak\t";
66     if (Subtarget->isAAPCS_ABI()) {
67       StaticCtorsSection = "\t.section .init_array,\"aw\",%init_array";
68       StaticDtorsSection = "\t.section .fini_array,\"aw\",%fini_array";
69     } else {
70       StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits";
71       StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits";
72     }
73     TLSDataSection = "\t.section .tdata,\"awT\",%progbits";
74     TLSBSSSection = "\t.section .tbss,\"awT\",%nobits";
75   }
76
77   ZeroDirective = "\t.space\t";
78   AlignmentIsInBytes = false;
79   Data64bitsDirective = 0;
80   CommentString = "@";
81   DataSection = "\t.data";
82   ConstantPoolSection = "\t.text\n";
83   COMMDirectiveTakesAlignment = false;
84   InlineAsmStart = "@ InlineAsm Start";
85   InlineAsmEnd = "@ InlineAsm End";
86   LCOMMDirective = "\t.lcomm\t";
87   isThumb = Subtarget->isThumb();
88 }
89
90 /// ARM-specific version of TargetAsmInfo::getInlineAsmLength.
91 unsigned ARMTargetAsmInfo::getInlineAsmLength(const char *Str) const {
92   // Count the number of bytes in the asm.
93   bool atInsnStart = true;
94   unsigned Length = 0;
95   for (; *Str; ++Str) {
96     if (atInsnStart) {
97       // Skip whitespace
98       while (*Str && isspace(*Str) && *Str != '\n')
99         Str++;
100       // Skip label
101       for (const char* p = Str; *p && !isspace(*p); p++)
102         if (*p == ':') {
103           Str = p+1;
104           break;
105         }
106       // Ignore everything from comment char(s) to EOL
107       if (strncmp(Str, CommentString, strlen(CommentString))==-0)
108         atInsnStart = false;
109       else {
110         // An instruction
111         atInsnStart = false;
112         if (isThumb) {
113           // BL and BLX <non-reg> are 4 bytes, all others 2.
114           const char*p = Str;
115           if ((*Str=='b' || *Str=='B') &&
116               (*(Str+1)=='l' || *(Str+1)=='L')) {
117             if (*(Str+2)=='x' || *(Str+2)=='X') {
118               const char* p = Str+3;
119               while (*p && isspace(*p))
120                 p++;
121               if (*p == 'r' || *p=='R')
122                 Length += 2;    // BLX reg
123               else
124                 Length += 4;    // BLX non-reg
125             }
126             else
127               Length += 4;    // BL
128           } else
129             Length += 2;    // Thumb anything else
130         }
131         else
132           Length += 4;    // ARM
133       }
134     }
135     if (*Str == '\n' || *Str == SeparatorChar)
136       atInsnStart = true;
137   }
138   return Length;
139 }