llvm.org GIT mirror llvm / 9320b80
Reapply 'ARM IAS: support .thumb_set' Re-apply the change after it was reverted to do conflicts due to another change being reverted. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204306 91177308-0d34-0410-b5e6-96231b3b80d8 Saleem Abdulrasool 6 years ago
4 changed file(s) with 264 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
471471 if (Symbol.isAbsolute() && Symbol.isVariable()) {
472472 if (const MCExpr *Value = Symbol.getVariableValue()) {
473473 int64_t IntValue;
474 if (Value->EvaluateAsAbsolute(IntValue, Layout))
475 return (uint64_t)IntValue;
474 if (Value->EvaluateAsAbsolute(IntValue, Layout)) {
475 if (Data.getFlags() & ELF_Other_ThumbFunc)
476 return static_cast(IntValue | 1);
477 else
478 return static_cast(IntValue);
479 }
476480 }
477481 }
478482
479483 if (!Symbol.isInSection())
480484 return 0;
481485
482
483486 if (Data.getFragment()) {
484487 if (Data.getFlags() & ELF_Other_ThumbFunc)
485 return Layout.getSymbolOffset(&Data)+1;
488 return Layout.getSymbolOffset(&Data) | 1;
486489 else
487490 return Layout.getSymbolOffset(&Data);
488491 }
577580 // Binding and Type share the same byte as upper and lower nibbles
578581 uint8_t Binding = MCELF::GetBinding(OrigData);
579582 uint8_t Type = mergeTypeForSet(MCELF::GetType(OrigData), MCELF::GetType(Data));
583 if (OrigData.getFlags() & ELF_Other_ThumbFunc)
584 Type = ELF::STT_FUNC;
580585 uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
581586
582587 // Other and Visibility share the same byte with Visibility using the lower
586591 Other |= Visibility;
587592
588593 uint64_t Value = SymbolValue(Data, Layout);
594 if (OrigData.getFlags() & ELF_Other_ThumbFunc)
595 Value |= 1;
589596 uint64_t Size = 0;
590597
591598 assert(!(Data.isCommon() && !Data.isExternal()));
2929 #include "llvm/MC/MCInst.h"
3030 #include "llvm/MC/MCInstrDesc.h"
3131 #include "llvm/MC/MCInstrInfo.h"
32 #include "llvm/MC/MCObjectFileInfo.h"
3233 #include "llvm/MC/MCParser/MCAsmLexer.h"
3334 #include "llvm/MC/MCParser/MCAsmParser.h"
3435 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
4041 #include "llvm/MC/MCTargetAsmParser.h"
4142 #include "llvm/Support/ARMBuildAttributes.h"
4243 #include "llvm/Support/ARMEHABI.h"
44 #include "llvm/Support/COFF.h"
4345 #include "llvm/Support/Debug.h"
4446 #include "llvm/Support/ELF.h"
4547 #include "llvm/Support/MathExtras.h"
228230 bool parseDirectiveObjectArch(SMLoc L);
229231 bool parseDirectiveArchExtension(SMLoc L);
230232 bool parseDirectiveAlign(SMLoc L);
233 bool parseDirectiveThumbSet(SMLoc L);
231234
232235 StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
233236 bool &CarrySetting, unsigned &ProcessorIMod,
80298032 return parseDirectiveArchExtension(DirectiveID.getLoc());
80308033 else if (IDVal == ".align")
80318034 return parseDirectiveAlign(DirectiveID.getLoc());
8035 else if (IDVal == ".thumb_set")
8036 return parseDirectiveThumbSet(DirectiveID.getLoc());
80328037 return true;
80338038 }
80348039
90829087 getStreamer().EmitCodeAlignment(4, 0);
90839088 else
90849089 getStreamer().EmitValueToAlignment(4, 0, 1, 0);
9090
9091 return false;
9092 }
9093
9094 /// parseDirectiveThumbSet
9095 /// ::= .thumb_set name, value
9096 bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
9097 StringRef Name;
9098 if (Parser.parseIdentifier(Name)) {
9099 TokError("expected identifier after '.thumb_set'");
9100 Parser.eatToEndOfStatement();
9101 return false;
9102 }
9103
9104 if (getLexer().isNot(AsmToken::Comma)) {
9105 TokError("expected comma after name '" + Name + "'");
9106 Parser.eatToEndOfStatement();
9107 return false;
9108 }
9109 Lex();
9110
9111 const MCExpr *Value;
9112 if (Parser.parseExpression(Value)) {
9113 TokError("missing expression");
9114 Parser.eatToEndOfStatement();
9115 return false;
9116 }
9117
9118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9119 TokError("unexpected token");
9120 Parser.eatToEndOfStatement();
9121 return false;
9122 }
9123 Lex();
9124
9125 MCSymbol *Alias = getContext().GetOrCreateSymbol(Name);
9126 if (const MCSymbolRefExpr *SRE = dyn_cast(Value)) {
9127 MCSymbol *Sym = getContext().LookupSymbol(SRE->getSymbol().getName());
9128 if (!Sym->isDefined()) {
9129 getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
9130 getStreamer().EmitAssignment(Alias, Value);
9131 return false;
9132 }
9133
9134 const MCObjectFileInfo::Environment Format =
9135 getContext().getObjectFileInfo()->getObjectFileType();
9136 switch (Format) {
9137 case MCObjectFileInfo::IsCOFF: {
9138 char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
9139 getStreamer().EmitCOFFSymbolType(Type);
9140 // .set values are always local in COFF
9141 getStreamer().EmitSymbolAttribute(Alias, MCSA_Local);
9142 break;
9143 }
9144 case MCObjectFileInfo::IsELF:
9145 getStreamer().EmitSymbolAttribute(Alias, MCSA_ELF_TypeFunction);
9146 break;
9147 case MCObjectFileInfo::IsMachO:
9148 break;
9149 }
9150 }
9151
9152 // FIXME: set the function as being a thumb function via the assembler
9153 getStreamer().EmitThumbFunc(Alias);
9154 getStreamer().EmitAssignment(Alias, Value);
90859155
90869156 return false;
90879157 }
0 @ RUN: not llvm-mc -triple armv7-eabi -o /dev/null 2>&1 %s | FileCheck %s
1
2 .syntax unified
3
4 .thumb
5
6 .thumb_set
7
8 @ CHECK: error: expected identifier after '.thumb_set'
9 @ CHECK: .thumb_set
10 @ CHECL: ^
11
12 .thumb_set ., 0x0b5e55ed
13
14 @ CHECK: error: expected identifier after '.thumb_set'
15 @ CHECK: .thumb_set ., 0x0b5e55ed
16 @ CHECK: ^
17
18 .thumb_set labelled, 0x1abe11ed
19 .thumb_set invalid, :lower16:labelled
20
21 @ CHECK: error: unknown token in expression
22 @ CHECK: .thumb_set invalid, :lower16:labelled
23 @ CHECK: ^
24
25 .thumb_set missing_comma
26
27 @ CHECK: error: expected comma after name 'missing_comma'
28 @ CHECK: .thumb_set missing_comma
29 @ CHECK: ^
30
31 .thumb_set missing_expression,
32
33 @ CHECK: error: missing expression
34 @ CHECK: .thumb_set missing_expression,
35 @ CHECK: ^
36
37 .thumb_set trailer_trash, 0x11fe1e55,
38
39 @ CHECK: error: unexpected token
40 @ CHECK: .thumb_set trailer_trash, 0x11fe1e55,
41 @ CHECK: ^
42
0 @ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s | llvm-readobj -t \
1 @ RUN: | FileCheck %s
2
3 .syntax unified
4
5 .arm
6
7 .type arm_func,%function
8 arm_func:
9 nop
10
11 .thumb_set alias_arm_func, arm_func
12
13 .thumb
14
15 .type thumb_func,%function
16 .thumb_func
17 thumb_func:
18 nop
19
20 .thumb_set alias_thumb_func, thumb_func
21
22 .thumb_set seedless, 0x5eed1e55
23 .thumb_set eggsalad, seedless + 0x87788358
24 .thumb_set faceless, ~eggsalad + 0xe133c002
25
26 .thumb_set alias_undefined_data, badblood
27
28 .data
29
30 .type badblood,%object
31 badblood:
32 .long 0xbadb100d
33
34 .type bedazzle,%object
35 bedazzle:
36 .long 0xbeda221e
37
38 .text
39 .thumb
40
41 .thumb_set alias_defined_data, bedazzle
42
43 .type alpha,%function
44 alpha:
45 nop
46
47 .type beta,%function
48 beta:
49 bkpt
50
51 .thumb_set beta, alpha
52
53 .thumb_set alias_undefined, undefined
54
55 @ CHECK: Symbol {
56 @ CHECK: Name: alias_arm_func
57 @ CHECK: Value: 0x1
58 @ CHECK: Type: Function
59 @ CHECK: }
60
61 @ CHECK: Symbol {
62 @ CHECK: Name: alias_defined_data
63 @ CHECK: Value: 0x5
64 @ CHECK: Type: Function
65 @ CHECK: }
66
67 @ CHECK: Symbol {
68 @ CHECK: Name: alias_thumb_func
69 @ CHECK: Value: 0x5
70 @ CHECK: Type: Function
71 @ CHECK: }
72
73 @ CHECK: Symbol {
74 @ CHECK: Name: alias_undefined_data
75 @ CHECK: Value: 0x0
76 @ CHECK: Type: Object
77 @ CHECK: }
78
79 @ CHECK: Symbol {
80 @ CHECK: Name: alpha
81 @ CHECK: Value: 0x6
82 @ XFAIL-CHECK: Value: 0x7
83 @ CHECK: Type: Function
84 @ CHECK: }
85
86 @ CHECK: Symbol {
87 @ CHECK: Name: arm_func
88 @ CHECK: Value: 0x0
89 @ CHECK: Type: Function
90 @ CHECK: }
91
92 @ CHECK: Symbol {
93 @ CHECK: Name: bedazzle
94 @ CHECK: Value: 0x4
95 @ CHECK: Type: Object
96 @ CHECK: }
97
98 @ CHECK: Symbol {
99 @ CHECK: Name: beta
100 @ CHECK: Value: 0x7
101 @ CHECK: Type: Function
102 @ CHECK: }
103
104 @ CHECK: Symbol {
105 @ CHECK: Name: eggsalad
106 @ CHECK: Value: 0xE665A1AD
107 @ CHECK: Type: Function
108 @ CHECK: }
109
110 @ CHECK: Symbol {
111 @ CHECK: Name: faceless
112 @ CHECK: Value: 0xFACE1E55
113 @ CHECK: Type: Function
114 @ CHECK: }
115
116 @ CHECK: Symbol {
117 @ CHECK: Name: seedless
118 @ CHECK: Value: 0x5EED1E55
119 @ CHECK: Type: Function
120 @ CHECK: }
121
122 @ CHECK: Symbol {
123 @ CHECK: Name: thumb_func
124 @ CHECK: Value: 0x5
125 @ CHECK: Type: Function
126 @ CHECK: }
127
128 @ CHECK: Symbol {
129 @ CHECK: Name: badblood
130 @ CHECK: Value: 0x0
131 @ CHECK: Type: Object
132 @ CHECK: }
133
134 @ CHECK: Symbol {
135 @ CHECK: Name: undefined
136 @ CHECK: Value: 0x0
137 @ CHECK: Type: None
138 @ CHECK: }
139