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
21using namespace llvm;
22
23#define DEBUG_TYPE "sparcmcexpr"
24
25StringRef 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
72uint16_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