1 //===-- VEMCExpr.cpp - VE 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 VE architecture (e.g. "%hi", "%lo", ...).
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "VEMCExpr.h"
15 #include "llvm/MC/MCAssembler.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCObjectStreamer.h"
18 #include "llvm/MC/MCSymbolELF.h"
19 #include "llvm/Object/ELF.h"
20 
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "vemcexpr"
24 
25 const VEMCExpr *VEMCExpr::create(VariantKind Kind, const MCExpr *Expr,
26                                  MCContext &Ctx) {
27   return new (Ctx) VEMCExpr(Kind, Expr);
28 }
29 
30 void VEMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
31 
32   bool closeParen = printVariantKind(OS, Kind);
33 
34   const MCExpr *Expr = getSubExpr();
35   Expr->print(OS, MAI);
36 
37   if (closeParen)
38     OS << ')';
39   printVariantKindSuffix(OS, Kind);
40 }
41 
42 bool VEMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) {
43   switch (Kind) {
44   case VK_VE_None:
45     return false;
46 
47   case VK_VE_HI32:
48   case VK_VE_LO32:
49     return false; // OS << "@<text>(";  break;
50   }
51   return true;
52 }
53 
54 void VEMCExpr::printVariantKindSuffix(raw_ostream &OS, VariantKind Kind) {
55   switch (Kind) {
56   case VK_VE_None:
57     break;
58   case VK_VE_HI32:
59     OS << "@hi";
60     break;
61   case VK_VE_LO32:
62     OS << "@lo";
63     break;
64   }
65 }
66 
67 VEMCExpr::VariantKind VEMCExpr::parseVariantKind(StringRef name) {
68   return StringSwitch<VEMCExpr::VariantKind>(name)
69       .Case("hi", VK_VE_HI32)
70       .Case("lo", VK_VE_LO32)
71       .Default(VK_VE_None);
72 }
73 
74 VE::Fixups VEMCExpr::getFixupKind(VEMCExpr::VariantKind Kind) {
75   switch (Kind) {
76   default:
77     llvm_unreachable("Unhandled VEMCExpr::VariantKind");
78   case VK_VE_HI32:
79     return VE::fixup_ve_hi32;
80   case VK_VE_LO32:
81     return VE::fixup_ve_lo32;
82   }
83 }
84 
85 bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
86                                          const MCAsmLayout *Layout,
87                                          const MCFixup *Fixup) const {
88   return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
89 }
90 
91 void VEMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
92   Streamer.visitUsedExpr(*getSubExpr());
93 }
94 
95 void VEMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
96   llvm_unreachable("TODO implement");
97 }
98