1 | //===-- LoongArchMCAsmInfo.cpp - LoongArch Asm properties ------*- C++ -*--===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains the declarations of the LoongArchMCAsmInfo properties. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "LoongArchMCAsmInfo.h" |
14 | #include "llvm/BinaryFormat/Dwarf.h" |
15 | #include "llvm/BinaryFormat/ELF.h" |
16 | #include "llvm/MC/MCContext.h" |
17 | #include "llvm/MC/MCStreamer.h" |
18 | #include "llvm/TargetParser/Triple.h" |
19 | |
20 | using namespace llvm; |
21 | |
22 | const LoongArchMCExpr *LoongArchMCExpr::create(const MCExpr *Expr, uint16_t S, |
23 | MCContext &Ctx, bool Hint) { |
24 | return new (Ctx) LoongArchMCExpr(Expr, S, Hint); |
25 | } |
26 | |
27 | static StringRef getLoongArchSpecifierName(uint16_t S) { |
28 | switch (S) { |
29 | default: |
30 | llvm_unreachable("Invalid ELF symbol kind" ); |
31 | case ELF::R_LARCH_B16: |
32 | return "b16" ; |
33 | case ELF::R_LARCH_B21: |
34 | return "b21" ; |
35 | case ELF::R_LARCH_ABS_HI20: |
36 | return "abs_hi20" ; |
37 | case ELF::R_LARCH_ABS_LO12: |
38 | return "abs_lo12" ; |
39 | case ELF::R_LARCH_ABS64_LO20: |
40 | return "abs64_lo20" ; |
41 | case ELF::R_LARCH_ABS64_HI12: |
42 | return "abs64_hi12" ; |
43 | case ELF::R_LARCH_PCALA_HI20: |
44 | return "pc_hi20" ; |
45 | case ELF::R_LARCH_PCALA_LO12: |
46 | return "pc_lo12" ; |
47 | case ELF::R_LARCH_PCALA64_LO20: |
48 | return "pc64_lo20" ; |
49 | case ELF::R_LARCH_PCALA64_HI12: |
50 | return "pc64_hi12" ; |
51 | case ELF::R_LARCH_GOT_PC_HI20: |
52 | return "got_pc_hi20" ; |
53 | case ELF::R_LARCH_GOT_PC_LO12: |
54 | return "got_pc_lo12" ; |
55 | case ELF::R_LARCH_GOT64_PC_LO20: |
56 | return "got64_pc_lo20" ; |
57 | case ELF::R_LARCH_GOT64_PC_HI12: |
58 | return "got64_pc_hi12" ; |
59 | case ELF::R_LARCH_GOT_HI20: |
60 | return "got_hi20" ; |
61 | case ELF::R_LARCH_GOT_LO12: |
62 | return "got_lo12" ; |
63 | case ELF::R_LARCH_GOT64_LO20: |
64 | return "got64_lo20" ; |
65 | case ELF::R_LARCH_GOT64_HI12: |
66 | return "got64_hi12" ; |
67 | case ELF::R_LARCH_TLS_LE_HI20: |
68 | return "le_hi20" ; |
69 | case ELF::R_LARCH_TLS_LE_LO12: |
70 | return "le_lo12" ; |
71 | case ELF::R_LARCH_TLS_LE64_LO20: |
72 | return "le64_lo20" ; |
73 | case ELF::R_LARCH_TLS_LE64_HI12: |
74 | return "le64_hi12" ; |
75 | case ELF::R_LARCH_TLS_IE_PC_HI20: |
76 | return "ie_pc_hi20" ; |
77 | case ELF::R_LARCH_TLS_IE_PC_LO12: |
78 | return "ie_pc_lo12" ; |
79 | case ELF::R_LARCH_TLS_IE64_PC_LO20: |
80 | return "ie64_pc_lo20" ; |
81 | case ELF::R_LARCH_TLS_IE64_PC_HI12: |
82 | return "ie64_pc_hi12" ; |
83 | case ELF::R_LARCH_TLS_IE_HI20: |
84 | return "ie_hi20" ; |
85 | case ELF::R_LARCH_TLS_IE_LO12: |
86 | return "ie_lo12" ; |
87 | case ELF::R_LARCH_TLS_IE64_LO20: |
88 | return "ie64_lo20" ; |
89 | case ELF::R_LARCH_TLS_IE64_HI12: |
90 | return "ie64_hi12" ; |
91 | case ELF::R_LARCH_TLS_LD_PC_HI20: |
92 | return "ld_pc_hi20" ; |
93 | case ELF::R_LARCH_TLS_LD_HI20: |
94 | return "ld_hi20" ; |
95 | case ELF::R_LARCH_TLS_GD_PC_HI20: |
96 | return "gd_pc_hi20" ; |
97 | case ELF::R_LARCH_TLS_GD_HI20: |
98 | return "gd_hi20" ; |
99 | case ELF::R_LARCH_CALL36: |
100 | return "call36" ; |
101 | case ELF::R_LARCH_TLS_DESC_PC_HI20: |
102 | return "desc_pc_hi20" ; |
103 | case ELF::R_LARCH_TLS_DESC_PC_LO12: |
104 | return "desc_pc_lo12" ; |
105 | case ELF::R_LARCH_TLS_DESC64_PC_LO20: |
106 | return "desc64_pc_lo20" ; |
107 | case ELF::R_LARCH_TLS_DESC64_PC_HI12: |
108 | return "desc64_pc_hi12" ; |
109 | case ELF::R_LARCH_TLS_DESC_HI20: |
110 | return "desc_hi20" ; |
111 | case ELF::R_LARCH_TLS_DESC_LO12: |
112 | return "desc_lo12" ; |
113 | case ELF::R_LARCH_TLS_DESC64_LO20: |
114 | return "desc64_lo20" ; |
115 | case ELF::R_LARCH_TLS_DESC64_HI12: |
116 | return "desc64_hi12" ; |
117 | case ELF::R_LARCH_TLS_DESC_LD: |
118 | return "desc_ld" ; |
119 | case ELF::R_LARCH_TLS_DESC_CALL: |
120 | return "desc_call" ; |
121 | case ELF::R_LARCH_TLS_LE_HI20_R: |
122 | return "le_hi20_r" ; |
123 | case ELF::R_LARCH_TLS_LE_ADD_R: |
124 | return "le_add_r" ; |
125 | case ELF::R_LARCH_TLS_LE_LO12_R: |
126 | return "le_lo12_r" ; |
127 | case ELF::R_LARCH_PCREL20_S2: |
128 | return "pcrel_20" ; |
129 | case ELF::R_LARCH_TLS_LD_PCREL20_S2: |
130 | return "ld_pcrel_20" ; |
131 | case ELF::R_LARCH_TLS_GD_PCREL20_S2: |
132 | return "gd_pcrel_20" ; |
133 | case ELF::R_LARCH_TLS_DESC_PCREL20_S2: |
134 | return "desc_pcrel_20" ; |
135 | } |
136 | } |
137 | |
138 | LoongArchMCExpr::Specifier LoongArch::parseSpecifier(StringRef name) { |
139 | return StringSwitch<LoongArchMCExpr::Specifier>(name) |
140 | .Case(S: "plt" , Value: ELF::R_LARCH_B26) |
141 | .Case(S: "b16" , Value: ELF::R_LARCH_B16) |
142 | .Case(S: "b21" , Value: ELF::R_LARCH_B21) |
143 | .Case(S: "b26" , Value: ELF::R_LARCH_B26) |
144 | .Case(S: "abs_hi20" , Value: ELF::R_LARCH_ABS_HI20) |
145 | .Case(S: "abs_lo12" , Value: ELF::R_LARCH_ABS_LO12) |
146 | .Case(S: "abs64_lo20" , Value: ELF::R_LARCH_ABS64_LO20) |
147 | .Case(S: "abs64_hi12" , Value: ELF::R_LARCH_ABS64_HI12) |
148 | .Case(S: "pc_hi20" , Value: ELF::R_LARCH_PCALA_HI20) |
149 | .Case(S: "pc_lo12" , Value: ELF::R_LARCH_PCALA_LO12) |
150 | .Case(S: "pc64_lo20" , Value: ELF::R_LARCH_PCALA64_LO20) |
151 | .Case(S: "pc64_hi12" , Value: ELF::R_LARCH_PCALA64_HI12) |
152 | .Case(S: "got_pc_hi20" , Value: ELF::R_LARCH_GOT_PC_HI20) |
153 | .Case(S: "got_pc_lo12" , Value: ELF::R_LARCH_GOT_PC_LO12) |
154 | .Case(S: "got64_pc_lo20" , Value: ELF::R_LARCH_GOT64_PC_LO20) |
155 | .Case(S: "got64_pc_hi12" , Value: ELF::R_LARCH_GOT64_PC_HI12) |
156 | .Case(S: "got_hi20" , Value: ELF::R_LARCH_GOT_HI20) |
157 | .Case(S: "got_lo12" , Value: ELF::R_LARCH_GOT_LO12) |
158 | .Case(S: "got64_lo20" , Value: ELF::R_LARCH_GOT64_LO20) |
159 | .Case(S: "got64_hi12" , Value: ELF::R_LARCH_GOT64_HI12) |
160 | .Case(S: "le_hi20" , Value: ELF::R_LARCH_TLS_LE_HI20) |
161 | .Case(S: "le_lo12" , Value: ELF::R_LARCH_TLS_LE_LO12) |
162 | .Case(S: "le64_lo20" , Value: ELF::R_LARCH_TLS_LE64_LO20) |
163 | .Case(S: "le64_hi12" , Value: ELF::R_LARCH_TLS_LE64_HI12) |
164 | .Case(S: "ie_pc_hi20" , Value: ELF::R_LARCH_TLS_IE_PC_HI20) |
165 | .Case(S: "ie_pc_lo12" , Value: ELF::R_LARCH_TLS_IE_PC_LO12) |
166 | .Case(S: "ie64_pc_lo20" , Value: ELF::R_LARCH_TLS_IE64_PC_LO20) |
167 | .Case(S: "ie64_pc_hi12" , Value: ELF::R_LARCH_TLS_IE64_PC_HI12) |
168 | .Case(S: "ie_hi20" , Value: ELF::R_LARCH_TLS_IE_HI20) |
169 | .Case(S: "ie_lo12" , Value: ELF::R_LARCH_TLS_IE_LO12) |
170 | .Case(S: "ie64_lo20" , Value: ELF::R_LARCH_TLS_IE64_LO20) |
171 | .Case(S: "ie64_hi12" , Value: ELF::R_LARCH_TLS_IE64_HI12) |
172 | .Case(S: "ld_pc_hi20" , Value: ELF::R_LARCH_TLS_LD_PC_HI20) |
173 | .Case(S: "ld_hi20" , Value: ELF::R_LARCH_TLS_LD_HI20) |
174 | .Case(S: "gd_pc_hi20" , Value: ELF::R_LARCH_TLS_GD_PC_HI20) |
175 | .Case(S: "gd_hi20" , Value: ELF::R_LARCH_TLS_GD_HI20) |
176 | .Case(S: "call36" , Value: ELF::R_LARCH_CALL36) |
177 | .Case(S: "desc_pc_hi20" , Value: ELF::R_LARCH_TLS_DESC_PC_HI20) |
178 | .Case(S: "desc_pc_lo12" , Value: ELF::R_LARCH_TLS_DESC_PC_LO12) |
179 | .Case(S: "desc64_pc_lo20" , Value: ELF::R_LARCH_TLS_DESC64_PC_LO20) |
180 | .Case(S: "desc64_pc_hi12" , Value: ELF::R_LARCH_TLS_DESC64_PC_HI12) |
181 | .Case(S: "desc_hi20" , Value: ELF::R_LARCH_TLS_DESC_HI20) |
182 | .Case(S: "desc_lo12" , Value: ELF::R_LARCH_TLS_DESC_LO12) |
183 | .Case(S: "desc64_lo20" , Value: ELF::R_LARCH_TLS_DESC64_LO20) |
184 | .Case(S: "desc64_hi12" , Value: ELF::R_LARCH_TLS_DESC64_HI12) |
185 | .Case(S: "desc_ld" , Value: ELF::R_LARCH_TLS_DESC_LD) |
186 | .Case(S: "desc_call" , Value: ELF::R_LARCH_TLS_DESC_CALL) |
187 | .Case(S: "le_hi20_r" , Value: ELF::R_LARCH_TLS_LE_HI20_R) |
188 | .Case(S: "le_add_r" , Value: ELF::R_LARCH_TLS_LE_ADD_R) |
189 | .Case(S: "le_lo12_r" , Value: ELF::R_LARCH_TLS_LE_LO12_R) |
190 | .Case(S: "pcrel_20" , Value: ELF::R_LARCH_PCREL20_S2) |
191 | .Case(S: "ld_pcrel_20" , Value: ELF::R_LARCH_TLS_LD_PCREL20_S2) |
192 | .Case(S: "gd_pcrel_20" , Value: ELF::R_LARCH_TLS_GD_PCREL20_S2) |
193 | .Case(S: "desc_pcrel_20" , Value: ELF::R_LARCH_TLS_DESC_PCREL20_S2) |
194 | .Default(Value: 0); |
195 | } |
196 | |
197 | void LoongArchMCAsmInfo::anchor() {} |
198 | |
199 | LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) { |
200 | CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4; |
201 | AlignmentIsInBytes = false; |
202 | Data8bitsDirective = "\t.byte\t" ; |
203 | Data16bitsDirective = "\t.half\t" ; |
204 | Data32bitsDirective = "\t.word\t" ; |
205 | Data64bitsDirective = "\t.dword\t" ; |
206 | ZeroDirective = "\t.space\t" ; |
207 | CommentString = "#" ; |
208 | SupportsDebugInformation = true; |
209 | DwarfRegNumForCFI = true; |
210 | ExceptionsType = ExceptionHandling::DwarfCFI; |
211 | } |
212 | |
213 | void LoongArchMCAsmInfo::printSpecifierExpr(raw_ostream &OS, |
214 | const MCSpecifierExpr &Expr) const { |
215 | auto S = Expr.getSpecifier(); |
216 | bool HasSpecifier = S != 0 && S != ELF::R_LARCH_B26; |
217 | if (HasSpecifier) |
218 | OS << '%' << getLoongArchSpecifierName(S) << '('; |
219 | printExpr(OS, *Expr.getSubExpr()); |
220 | if (HasSpecifier) |
221 | OS << ')'; |
222 | } |
223 | |