xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
parseSpecifierName(StringRef name)29 RISCV::Specifier RISCV::parseSpecifierName(StringRef name) {
30   return StringSwitch<RISCV::Specifier>(name)
31       .Case("lo", RISCV::S_LO)
32       .Case("hi", ELF::R_RISCV_HI20)
33       .Case("pcrel_lo", RISCV::S_PCREL_LO)
34       .Case("pcrel_hi", ELF::R_RISCV_PCREL_HI20)
35       .Case("got_pcrel_hi", ELF::R_RISCV_GOT_HI20)
36       .Case("tprel_lo", RISCV::S_TPREL_LO)
37       .Case("tprel_hi", ELF::R_RISCV_TPREL_HI20)
38       .Case("tprel_add", ELF::R_RISCV_TPREL_ADD)
39       .Case("tls_ie_pcrel_hi", ELF::R_RISCV_TLS_GOT_HI20)
40       .Case("tls_gd_pcrel_hi", ELF::R_RISCV_TLS_GD_HI20)
41       .Case("tlsdesc_hi", ELF::R_RISCV_TLSDESC_HI20)
42       .Case("tlsdesc_load_lo", ELF::R_RISCV_TLSDESC_LOAD_LO12)
43       .Case("tlsdesc_add_lo", ELF::R_RISCV_TLSDESC_ADD_LO12)
44       .Case("tlsdesc_call", ELF::R_RISCV_TLSDESC_CALL)
45       .Case("qc.abs20", RISCV::S_QC_ABS20)
46       // Used in data directives
47       .Case("pltpcrel", ELF::R_RISCV_PLT32)
48       .Case("gotpcrel", ELF::R_RISCV_GOT32_PCREL)
49       .Default(0);
50 }
51 
getSpecifierName(Specifier S)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