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