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
25using namespace llvm;
26
27#define DEBUG_TYPE "riscvmcexpr"
28
29RISCV::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
52StringRef 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