/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- SparcMCExpr.cpp - Sparc specific MC expression classes --------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the implementation of the assembly expression modifiers |
11 | | // accepted by the Sparc architecture (e.g. "%hi", "%lo", ...). |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "SparcMCExpr.h" |
16 | | #include "llvm/MC/MCAssembler.h" |
17 | | #include "llvm/MC/MCContext.h" |
18 | | #include "llvm/MC/MCObjectStreamer.h" |
19 | | #include "llvm/MC/MCSymbolELF.h" |
20 | | #include "llvm/Object/ELF.h" |
21 | | |
22 | | using namespace llvm; |
23 | | |
24 | | #define DEBUG_TYPE "sparcmcexpr" |
25 | | |
26 | | const SparcMCExpr* |
27 | | SparcMCExpr::create(VariantKind Kind, const MCExpr *Expr, |
28 | 1.23k | MCContext &Ctx) { |
29 | 1.23k | return new (Ctx) SparcMCExpr(Kind, Expr); |
30 | 1.23k | } |
31 | | |
32 | 1.16k | void SparcMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { |
33 | 1.16k | |
34 | 1.16k | bool closeParen = printVariantKind(OS, Kind); |
35 | 1.16k | |
36 | 1.16k | const MCExpr *Expr = getSubExpr(); |
37 | 1.16k | Expr->print(OS, MAI); |
38 | 1.16k | |
39 | 1.16k | if (closeParen) |
40 | 630 | OS << ')'; |
41 | 1.16k | } |
42 | | |
43 | | bool SparcMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) |
44 | 1.32k | { |
45 | 1.32k | bool closeParen = true; |
46 | 1.32k | switch (Kind) { |
47 | 672 | case VK_Sparc_None: closeParen = false; break; |
48 | 168 | case VK_Sparc_LO: OS << "%lo("; break; |
49 | 181 | case VK_Sparc_HI: OS << "%hi("; break; |
50 | 32 | case VK_Sparc_H44: OS << "%h44("; break; |
51 | 32 | case VK_Sparc_M44: OS << "%m44("; break; |
52 | 36 | case VK_Sparc_L44: OS << "%l44("; break; |
53 | 9 | case VK_Sparc_HH: OS << "%hh("; break; |
54 | 9 | case VK_Sparc_HM: OS << "%hm("; break; |
55 | 1.32k | // FIXME: use %pc22/%pc10, if system assembler supports them. |
56 | 22 | case VK_Sparc_PC22: OS << "%hi("; break; |
57 | 22 | case VK_Sparc_PC10: OS << "%lo("; break; |
58 | 1.32k | // FIXME: use %got22/%got10, if system assembler supports them. |
59 | 30 | case VK_Sparc_GOT22: OS << "%hi("; break; |
60 | 30 | case VK_Sparc_GOT10: OS << "%lo("; break; |
61 | 20 | case VK_Sparc_WPLT30: closeParen = false; break; |
62 | 4 | case VK_Sparc_R_DISP32: OS << "%r_disp32("; break; |
63 | 2 | case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break; |
64 | 2 | case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break; |
65 | 2 | case VK_Sparc_TLS_GD_ADD: OS << "%tgd_add("; break; |
66 | 2 | case VK_Sparc_TLS_GD_CALL: OS << "%tgd_call("; break; |
67 | 6 | case VK_Sparc_TLS_LDM_HI22: OS << "%tldm_hi22("; break; |
68 | 6 | case VK_Sparc_TLS_LDM_LO10: OS << "%tldm_lo10("; break; |
69 | 2 | case VK_Sparc_TLS_LDM_ADD: OS << "%tldm_add("; break; |
70 | 2 | case VK_Sparc_TLS_LDM_CALL: OS << "%tldm_call("; break; |
71 | 6 | case VK_Sparc_TLS_LDO_HIX22: OS << "%tldo_hix22("; break; |
72 | 6 | case VK_Sparc_TLS_LDO_LOX10: OS << "%tldo_lox10("; break; |
73 | 2 | case VK_Sparc_TLS_LDO_ADD: OS << "%tldo_add("; break; |
74 | 2 | case VK_Sparc_TLS_IE_HI22: OS << "%tie_hi22("; break; |
75 | 2 | case VK_Sparc_TLS_IE_LO10: OS << "%tie_lo10("; break; |
76 | 1 | case VK_Sparc_TLS_IE_LD: OS << "%tie_ld("; break; |
77 | 1 | case VK_Sparc_TLS_IE_LDX: OS << "%tie_ldx("; break; |
78 | 2 | case VK_Sparc_TLS_IE_ADD: OS << "%tie_add("; break; |
79 | 6 | case VK_Sparc_TLS_LE_HIX22: OS << "%tle_hix22("; break; |
80 | 6 | case VK_Sparc_TLS_LE_LOX10: OS << "%tle_lox10("; break; |
81 | 1.32k | } |
82 | 1.32k | return closeParen; |
83 | 1.32k | } |
84 | | |
85 | | SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name) |
86 | 68 | { |
87 | 68 | return StringSwitch<SparcMCExpr::VariantKind>(name) |
88 | 68 | .Case("lo", VK_Sparc_LO) |
89 | 68 | .Case("hi", VK_Sparc_HI) |
90 | 68 | .Case("h44", VK_Sparc_H44) |
91 | 68 | .Case("m44", VK_Sparc_M44) |
92 | 68 | .Case("l44", VK_Sparc_L44) |
93 | 68 | .Case("hh", VK_Sparc_HH) |
94 | 68 | .Case("hm", VK_Sparc_HM) |
95 | 68 | .Case("pc22", VK_Sparc_PC22) |
96 | 68 | .Case("pc10", VK_Sparc_PC10) |
97 | 68 | .Case("got22", VK_Sparc_GOT22) |
98 | 68 | .Case("got10", VK_Sparc_GOT10) |
99 | 68 | .Case("r_disp32", VK_Sparc_R_DISP32) |
100 | 68 | .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22) |
101 | 68 | .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10) |
102 | 68 | .Case("tgd_add", VK_Sparc_TLS_GD_ADD) |
103 | 68 | .Case("tgd_call", VK_Sparc_TLS_GD_CALL) |
104 | 68 | .Case("tldm_hi22", VK_Sparc_TLS_LDM_HI22) |
105 | 68 | .Case("tldm_lo10", VK_Sparc_TLS_LDM_LO10) |
106 | 68 | .Case("tldm_add", VK_Sparc_TLS_LDM_ADD) |
107 | 68 | .Case("tldm_call", VK_Sparc_TLS_LDM_CALL) |
108 | 68 | .Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22) |
109 | 68 | .Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10) |
110 | 68 | .Case("tldo_add", VK_Sparc_TLS_LDO_ADD) |
111 | 68 | .Case("tie_hi22", VK_Sparc_TLS_IE_HI22) |
112 | 68 | .Case("tie_lo10", VK_Sparc_TLS_IE_LO10) |
113 | 68 | .Case("tie_ld", VK_Sparc_TLS_IE_LD) |
114 | 68 | .Case("tie_ldx", VK_Sparc_TLS_IE_LDX) |
115 | 68 | .Case("tie_add", VK_Sparc_TLS_IE_ADD) |
116 | 68 | .Case("tle_hix22", VK_Sparc_TLS_LE_HIX22) |
117 | 68 | .Case("tle_lox10", VK_Sparc_TLS_LE_LOX10) |
118 | 68 | .Default(VK_Sparc_None); |
119 | 68 | } |
120 | | |
121 | 194 | Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) { |
122 | 194 | switch (Kind) { |
123 | 0 | default: 0 llvm_unreachable0 ("Unhandled SparcMCExpr::VariantKind"); |
124 | 31 | case VK_Sparc_LO: return Sparc::fixup_sparc_lo10; |
125 | 47 | case VK_Sparc_HI: return Sparc::fixup_sparc_hi22; |
126 | 6 | case VK_Sparc_H44: return Sparc::fixup_sparc_h44; |
127 | 6 | case VK_Sparc_M44: return Sparc::fixup_sparc_m44; |
128 | 6 | case VK_Sparc_L44: return Sparc::fixup_sparc_l44; |
129 | 2 | case VK_Sparc_HH: return Sparc::fixup_sparc_hh; |
130 | 2 | case VK_Sparc_HM: return Sparc::fixup_sparc_hm; |
131 | 7 | case VK_Sparc_PC22: return Sparc::fixup_sparc_pc22; |
132 | 7 | case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10; |
133 | 5 | case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22; |
134 | 5 | case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10; |
135 | 0 | case VK_Sparc_WPLT30: return Sparc::fixup_sparc_wplt30; |
136 | 2 | case VK_Sparc_TLS_GD_HI22: return Sparc::fixup_sparc_tls_gd_hi22; |
137 | 2 | case VK_Sparc_TLS_GD_LO10: return Sparc::fixup_sparc_tls_gd_lo10; |
138 | 2 | case VK_Sparc_TLS_GD_ADD: return Sparc::fixup_sparc_tls_gd_add; |
139 | 2 | case VK_Sparc_TLS_GD_CALL: return Sparc::fixup_sparc_tls_gd_call; |
140 | 8 | case VK_Sparc_TLS_LDM_HI22: return Sparc::fixup_sparc_tls_ldm_hi22; |
141 | 8 | case VK_Sparc_TLS_LDM_LO10: return Sparc::fixup_sparc_tls_ldm_lo10; |
142 | 2 | case VK_Sparc_TLS_LDM_ADD: return Sparc::fixup_sparc_tls_ldm_add; |
143 | 2 | case VK_Sparc_TLS_LDM_CALL: return Sparc::fixup_sparc_tls_ldm_call; |
144 | 8 | case VK_Sparc_TLS_LDO_HIX22: return Sparc::fixup_sparc_tls_ldo_hix22; |
145 | 8 | case VK_Sparc_TLS_LDO_LOX10: return Sparc::fixup_sparc_tls_ldo_lox10; |
146 | 2 | case VK_Sparc_TLS_LDO_ADD: return Sparc::fixup_sparc_tls_ldo_add; |
147 | 2 | case VK_Sparc_TLS_IE_HI22: return Sparc::fixup_sparc_tls_ie_hi22; |
148 | 2 | case VK_Sparc_TLS_IE_LO10: return Sparc::fixup_sparc_tls_ie_lo10; |
149 | 1 | case VK_Sparc_TLS_IE_LD: return Sparc::fixup_sparc_tls_ie_ld; |
150 | 1 | case VK_Sparc_TLS_IE_LDX: return Sparc::fixup_sparc_tls_ie_ldx; |
151 | 2 | case VK_Sparc_TLS_IE_ADD: return Sparc::fixup_sparc_tls_ie_add; |
152 | 8 | case VK_Sparc_TLS_LE_HIX22: return Sparc::fixup_sparc_tls_le_hix22; |
153 | 8 | case VK_Sparc_TLS_LE_LOX10: return Sparc::fixup_sparc_tls_le_lox10; |
154 | 0 | } |
155 | 0 | } |
156 | | |
157 | | bool |
158 | | SparcMCExpr::evaluateAsRelocatableImpl(MCValue &Res, |
159 | | const MCAsmLayout *Layout, |
160 | 155 | const MCFixup *Fixup) const { |
161 | 155 | return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup); |
162 | 155 | } |
163 | | |
164 | 58 | static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { |
165 | 58 | switch (Expr->getKind()) { |
166 | 0 | case MCExpr::Target: |
167 | 0 | llvm_unreachable("Can't handle nested target expr!"); |
168 | 0 | break; |
169 | 58 | |
170 | 0 | case MCExpr::Constant: |
171 | 0 | break; |
172 | 58 | |
173 | 0 | case MCExpr::Binary: { |
174 | 0 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); |
175 | 0 | fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); |
176 | 0 | fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); |
177 | 0 | break; |
178 | 58 | } |
179 | 58 | |
180 | 58 | case MCExpr::SymbolRef: { |
181 | 58 | const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); |
182 | 58 | cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS); |
183 | 58 | break; |
184 | 58 | } |
185 | 58 | |
186 | 0 | case MCExpr::Unary: |
187 | 0 | fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); |
188 | 0 | break; |
189 | 58 | } |
190 | 58 | |
191 | 58 | } |
192 | | |
193 | 141 | void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { |
194 | 141 | switch(getKind()) { |
195 | 83 | default: return; |
196 | 58 | case VK_Sparc_TLS_GD_HI22: |
197 | 58 | case VK_Sparc_TLS_GD_LO10: |
198 | 58 | case VK_Sparc_TLS_GD_ADD: |
199 | 58 | case VK_Sparc_TLS_GD_CALL: |
200 | 58 | case VK_Sparc_TLS_LDM_HI22: |
201 | 58 | case VK_Sparc_TLS_LDM_LO10: |
202 | 58 | case VK_Sparc_TLS_LDM_ADD: |
203 | 58 | case VK_Sparc_TLS_LDM_CALL: |
204 | 58 | case VK_Sparc_TLS_LDO_HIX22: |
205 | 58 | case VK_Sparc_TLS_LDO_LOX10: |
206 | 58 | case VK_Sparc_TLS_LDO_ADD: |
207 | 58 | case VK_Sparc_TLS_IE_HI22: |
208 | 58 | case VK_Sparc_TLS_IE_LO10: |
209 | 58 | case VK_Sparc_TLS_IE_LD: |
210 | 58 | case VK_Sparc_TLS_IE_LDX: |
211 | 58 | case VK_Sparc_TLS_IE_ADD: |
212 | 58 | case VK_Sparc_TLS_LE_HIX22: |
213 | 58 | case VK_Sparc_TLS_LE_LOX10: break; |
214 | 58 | } |
215 | 58 | fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); |
216 | 58 | } |
217 | | |
218 | 145 | void SparcMCExpr::visitUsedExpr(MCStreamer &Streamer) const { |
219 | 145 | Streamer.visitUsedExpr(*getSubExpr()); |
220 | 145 | } |