1 | //===-- SparcMCExpr.cpp - Sparc specific MC expression classes --------===// |
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 implementation of the assembly expression modifiers |
10 | // accepted by the Sparc architecture (e.g. "%hi", "%lo", ...). |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "MCTargetDesc/SparcMCAsmInfo.h" |
15 | #include "llvm/BinaryFormat/ELF.h" |
16 | #include "llvm/MC/MCAssembler.h" |
17 | #include "llvm/MC/MCContext.h" |
18 | #include "llvm/MC/MCObjectStreamer.h" |
19 | #include "llvm/MC/MCValue.h" |
20 | |
21 | using namespace llvm; |
22 | |
23 | #define DEBUG_TYPE "sparcmcexpr" |
24 | |
25 | StringRef Sparc::getSpecifierName(uint16_t S) { |
26 | // clang-format off |
27 | switch (uint16_t(S)) { |
28 | case 0: return {}; |
29 | case ELF::R_SPARC_LO10: return "lo" ; |
30 | case ELF::R_SPARC_HI22: return "hi" ; |
31 | case ELF::R_SPARC_H44: return "h44" ; |
32 | case ELF::R_SPARC_M44: return "m44" ; |
33 | case ELF::R_SPARC_L44: return "l44" ; |
34 | case ELF::R_SPARC_HH22: return "hh" ; |
35 | case ELF::R_SPARC_HM10: return "hm" ; |
36 | case ELF::R_SPARC_LM22: return "lm" ; |
37 | // FIXME: use %pc22/%pc10, if system assembler supports them. |
38 | case ELF::R_SPARC_PC22: return "hi" ; |
39 | case ELF::R_SPARC_PC10: return "lo" ; |
40 | case ELF::R_SPARC_GOT22: return "hi" ; |
41 | case ELF::R_SPARC_GOT10: return "lo" ; |
42 | case ELF::R_SPARC_GOT13: return {}; |
43 | case ELF::R_SPARC_DISP32: return "r_disp32" ; |
44 | case ELF::R_SPARC_TLS_GD_HI22: return "tgd_hi22" ; |
45 | case ELF::R_SPARC_TLS_GD_LO10: return "tgd_lo10" ; |
46 | case ELF::R_SPARC_TLS_GD_ADD: return "tgd_add" ; |
47 | case ELF::R_SPARC_TLS_GD_CALL: return "tgd_call" ; |
48 | case ELF::R_SPARC_TLS_LDM_HI22: return "tldm_hi22" ; |
49 | case ELF::R_SPARC_TLS_LDM_LO10: return "tldm_lo10" ; |
50 | case ELF::R_SPARC_TLS_LDM_ADD: return "tldm_add" ; |
51 | case ELF::R_SPARC_TLS_LDM_CALL: return "tldm_call" ; |
52 | case ELF::R_SPARC_TLS_LDO_HIX22: return "tldo_hix22" ; |
53 | case ELF::R_SPARC_TLS_LDO_LOX10: return "tldo_lox10" ; |
54 | case ELF::R_SPARC_TLS_LDO_ADD: return "tldo_add" ; |
55 | case ELF::R_SPARC_TLS_IE_HI22: return "tie_hi22" ; |
56 | case ELF::R_SPARC_TLS_IE_LO10: return "tie_lo10" ; |
57 | case ELF::R_SPARC_TLS_IE_LD: return "tie_ld" ; |
58 | case ELF::R_SPARC_TLS_IE_LDX: return "tie_ldx" ; |
59 | case ELF::R_SPARC_TLS_IE_ADD: return "tie_add" ; |
60 | case ELF::R_SPARC_TLS_LE_HIX22: return "tle_hix22" ; |
61 | case ELF::R_SPARC_TLS_LE_LOX10: return "tle_lox10" ; |
62 | case ELF::R_SPARC_HIX22: return "hix" ; |
63 | case ELF::R_SPARC_LOX10: return "lox" ; |
64 | case ELF::R_SPARC_GOTDATA_OP_HIX22: return "gdop_hix22" ; |
65 | case ELF::R_SPARC_GOTDATA_OP_LOX10: return "gdop_lox10" ; |
66 | case ELF::R_SPARC_GOTDATA_OP: return "gdop" ; |
67 | } |
68 | // clang-format on |
69 | llvm_unreachable("Unhandled SparcMCExpr::Specifier" ); |
70 | } |
71 | |
72 | uint16_t Sparc::parseSpecifier(StringRef name) { |
73 | return StringSwitch<uint16_t>(name) |
74 | .Case(S: "lo" , Value: ELF::R_SPARC_LO10) |
75 | .Case(S: "hi" , Value: ELF::R_SPARC_HI22) |
76 | .Case(S: "h44" , Value: ELF::R_SPARC_H44) |
77 | .Case(S: "m44" , Value: ELF::R_SPARC_M44) |
78 | .Case(S: "l44" , Value: ELF::R_SPARC_L44) |
79 | .Case(S: "hh" , Value: ELF::R_SPARC_HH22) |
80 | // Nonstandard GNU extension |
81 | .Case(S: "uhi" , Value: ELF::R_SPARC_HH22) |
82 | .Case(S: "hm" , Value: ELF::R_SPARC_HM10) |
83 | // Nonstandard GNU extension |
84 | .Case(S: "ulo" , Value: ELF::R_SPARC_HM10) |
85 | .Case(S: "lm" , Value: ELF::R_SPARC_LM22) |
86 | .Case(S: "pc22" , Value: ELF::R_SPARC_PC22) |
87 | .Case(S: "pc10" , Value: ELF::R_SPARC_PC10) |
88 | .Case(S: "got22" , Value: ELF::R_SPARC_GOT22) |
89 | .Case(S: "got10" , Value: ELF::R_SPARC_GOT10) |
90 | .Case(S: "got13" , Value: ELF::R_SPARC_GOT13) |
91 | .Case(S: "r_disp32" , Value: ELF::R_SPARC_DISP32) |
92 | .Case(S: "tgd_hi22" , Value: ELF::R_SPARC_TLS_GD_HI22) |
93 | .Case(S: "tgd_lo10" , Value: ELF::R_SPARC_TLS_GD_LO10) |
94 | .Case(S: "tgd_add" , Value: ELF::R_SPARC_TLS_GD_ADD) |
95 | .Case(S: "tgd_call" , Value: ELF::R_SPARC_TLS_GD_CALL) |
96 | .Case(S: "tldm_hi22" , Value: ELF::R_SPARC_TLS_LDM_HI22) |
97 | .Case(S: "tldm_lo10" , Value: ELF::R_SPARC_TLS_LDM_LO10) |
98 | .Case(S: "tldm_add" , Value: ELF::R_SPARC_TLS_LDM_ADD) |
99 | .Case(S: "tldm_call" , Value: ELF::R_SPARC_TLS_LDM_CALL) |
100 | .Case(S: "tldo_hix22" , Value: ELF::R_SPARC_TLS_LDO_HIX22) |
101 | .Case(S: "tldo_lox10" , Value: ELF::R_SPARC_TLS_LDO_LOX10) |
102 | .Case(S: "tldo_add" , Value: ELF::R_SPARC_TLS_LDO_ADD) |
103 | .Case(S: "tie_hi22" , Value: ELF::R_SPARC_TLS_IE_HI22) |
104 | .Case(S: "tie_lo10" , Value: ELF::R_SPARC_TLS_IE_LO10) |
105 | .Case(S: "tie_ld" , Value: ELF::R_SPARC_TLS_IE_LD) |
106 | .Case(S: "tie_ldx" , Value: ELF::R_SPARC_TLS_IE_LDX) |
107 | .Case(S: "tie_add" , Value: ELF::R_SPARC_TLS_IE_ADD) |
108 | .Case(S: "tle_hix22" , Value: ELF::R_SPARC_TLS_LE_HIX22) |
109 | .Case(S: "tle_lox10" , Value: ELF::R_SPARC_TLS_LE_LOX10) |
110 | .Case(S: "hix" , Value: ELF::R_SPARC_HIX22) |
111 | .Case(S: "lox" , Value: ELF::R_SPARC_LOX10) |
112 | .Case(S: "gdop_hix22" , Value: ELF::R_SPARC_GOTDATA_OP_HIX22) |
113 | .Case(S: "gdop_lox10" , Value: ELF::R_SPARC_GOTDATA_OP_LOX10) |
114 | .Case(S: "gdop" , Value: ELF::R_SPARC_GOTDATA_OP) |
115 | .Default(Value: 0); |
116 | } |
117 | |