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