| 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 | |