1 | //===-- RISCVMCExpr.cpp - RISC-V 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 RISC-V architecture (e.g. ":lo12:", ":gottprel_g1:", ...). |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "MCTargetDesc/RISCVAsmBackend.h" |
15 | #include "MCTargetDesc/RISCVMCAsmInfo.h" |
16 | #include "RISCVFixupKinds.h" |
17 | #include "llvm/BinaryFormat/ELF.h" |
18 | #include "llvm/MC/MCAssembler.h" |
19 | #include "llvm/MC/MCContext.h" |
20 | #include "llvm/MC/MCStreamer.h" |
21 | #include "llvm/MC/MCValue.h" |
22 | #include "llvm/Support/Casting.h" |
23 | #include "llvm/Support/ErrorHandling.h" |
24 | |
25 | using namespace llvm; |
26 | |
27 | #define DEBUG_TYPE "riscvmcexpr" |
28 | |
29 | RISCV::Specifier RISCV::parseSpecifierName(StringRef name) { |
30 | return StringSwitch<RISCV::Specifier>(name) |
31 | .Case(S: "lo" , Value: RISCV::S_LO) |
32 | .Case(S: "hi" , Value: ELF::R_RISCV_HI20) |
33 | .Case(S: "pcrel_lo" , Value: RISCV::S_PCREL_LO) |
34 | .Case(S: "pcrel_hi" , Value: ELF::R_RISCV_PCREL_HI20) |
35 | .Case(S: "got_pcrel_hi" , Value: ELF::R_RISCV_GOT_HI20) |
36 | .Case(S: "tprel_lo" , Value: RISCV::S_TPREL_LO) |
37 | .Case(S: "tprel_hi" , Value: ELF::R_RISCV_TPREL_HI20) |
38 | .Case(S: "tprel_add" , Value: ELF::R_RISCV_TPREL_ADD) |
39 | .Case(S: "tls_ie_pcrel_hi" , Value: ELF::R_RISCV_TLS_GOT_HI20) |
40 | .Case(S: "tls_gd_pcrel_hi" , Value: ELF::R_RISCV_TLS_GD_HI20) |
41 | .Case(S: "tlsdesc_hi" , Value: ELF::R_RISCV_TLSDESC_HI20) |
42 | .Case(S: "tlsdesc_load_lo" , Value: ELF::R_RISCV_TLSDESC_LOAD_LO12) |
43 | .Case(S: "tlsdesc_add_lo" , Value: ELF::R_RISCV_TLSDESC_ADD_LO12) |
44 | .Case(S: "tlsdesc_call" , Value: ELF::R_RISCV_TLSDESC_CALL) |
45 | .Case(S: "qc.abs20" , Value: RISCV::S_QC_ABS20) |
46 | // Used in data directives |
47 | .Case(S: "pltpcrel" , Value: ELF::R_RISCV_PLT32) |
48 | .Case(S: "gotpcrel" , Value: ELF::R_RISCV_GOT32_PCREL) |
49 | .Default(Value: 0); |
50 | } |
51 | |
52 | StringRef RISCV::getSpecifierName(Specifier S) { |
53 | switch (S) { |
54 | case RISCV::S_None: |
55 | llvm_unreachable("not used as %specifier()" ); |
56 | case RISCV::S_LO: |
57 | return "lo" ; |
58 | case ELF::R_RISCV_HI20: |
59 | return "hi" ; |
60 | case RISCV::S_PCREL_LO: |
61 | return "pcrel_lo" ; |
62 | case ELF::R_RISCV_PCREL_HI20: |
63 | return "pcrel_hi" ; |
64 | case ELF::R_RISCV_GOT_HI20: |
65 | return "got_pcrel_hi" ; |
66 | case RISCV::S_TPREL_LO: |
67 | return "tprel_lo" ; |
68 | case ELF::R_RISCV_TPREL_HI20: |
69 | return "tprel_hi" ; |
70 | case ELF::R_RISCV_TPREL_ADD: |
71 | return "tprel_add" ; |
72 | case ELF::R_RISCV_TLS_GOT_HI20: |
73 | return "tls_ie_pcrel_hi" ; |
74 | case ELF::R_RISCV_TLSDESC_HI20: |
75 | return "tlsdesc_hi" ; |
76 | case ELF::R_RISCV_TLSDESC_LOAD_LO12: |
77 | return "tlsdesc_load_lo" ; |
78 | case ELF::R_RISCV_TLSDESC_ADD_LO12: |
79 | return "tlsdesc_add_lo" ; |
80 | case ELF::R_RISCV_TLSDESC_CALL: |
81 | return "tlsdesc_call" ; |
82 | case ELF::R_RISCV_TLS_GD_HI20: |
83 | return "tls_gd_pcrel_hi" ; |
84 | case ELF::R_RISCV_CALL_PLT: |
85 | return "call_plt" ; |
86 | case ELF::R_RISCV_32_PCREL: |
87 | return "32_pcrel" ; |
88 | case ELF::R_RISCV_GOT32_PCREL: |
89 | return "gotpcrel" ; |
90 | case ELF::R_RISCV_PLT32: |
91 | return "pltpcrel" ; |
92 | case RISCV::S_QC_ABS20: |
93 | return "qc.abs20" ; |
94 | } |
95 | llvm_unreachable("Invalid ELF symbol kind" ); |
96 | } |
97 | |