LLVM  9.0.0svn
PPCMCExpr.cpp
Go to the documentation of this file.
1 //===-- PPCMCExpr.cpp - PPC 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 #include "PPCMCExpr.h"
10 #include "PPCFixupKinds.h"
11 #include "llvm/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCContext.h"
15 
16 using namespace llvm;
17 
18 #define DEBUG_TYPE "ppcmcexpr"
19 
20 const PPCMCExpr*
22  bool isDarwin, MCContext &Ctx) {
23  return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin);
24 }
25 
26 void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
27  if (isDarwinSyntax()) {
28  switch (Kind) {
29  default: llvm_unreachable("Invalid kind!");
30  case VK_PPC_LO: OS << "lo16"; break;
31  case VK_PPC_HI: OS << "hi16"; break;
32  case VK_PPC_HA: OS << "ha16"; break;
33  }
34 
35  OS << '(';
36  getSubExpr()->print(OS, MAI);
37  OS << ')';
38  } else {
39  getSubExpr()->print(OS, MAI);
40 
41  switch (Kind) {
42  default: llvm_unreachable("Invalid kind!");
43  case VK_PPC_LO: OS << "@l"; break;
44  case VK_PPC_HI: OS << "@h"; break;
45  case VK_PPC_HA: OS << "@ha"; break;
46  case VK_PPC_HIGH: OS << "@high"; break;
47  case VK_PPC_HIGHA: OS << "@higha"; break;
48  case VK_PPC_HIGHER: OS << "@higher"; break;
49  case VK_PPC_HIGHERA: OS << "@highera"; break;
50  case VK_PPC_HIGHEST: OS << "@highest"; break;
51  case VK_PPC_HIGHESTA: OS << "@highesta"; break;
52  }
53  }
54 }
55 
56 bool
57 PPCMCExpr::evaluateAsConstant(int64_t &Res) const {
58  MCValue Value;
59 
60  if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr))
61  return false;
62 
63  if (!Value.isAbsolute())
64  return false;
65 
66  Res = evaluateAsInt64(Value.getConstant());
67  return true;
68 }
69 
70 int64_t
71 PPCMCExpr::evaluateAsInt64(int64_t Value) const {
72  switch (Kind) {
73  case VK_PPC_LO:
74  return Value & 0xffff;
75  case VK_PPC_HI:
76  return (Value >> 16) & 0xffff;
77  case VK_PPC_HA:
78  return ((Value + 0x8000) >> 16) & 0xffff;
79  case VK_PPC_HIGH:
80  return (Value >> 16) & 0xffff;
81  case VK_PPC_HIGHA:
82  return ((Value + 0x8000) >> 16) & 0xffff;
83  case VK_PPC_HIGHER:
84  return (Value >> 32) & 0xffff;
85  case VK_PPC_HIGHERA:
86  return ((Value + 0x8000) >> 32) & 0xffff;
87  case VK_PPC_HIGHEST:
88  return (Value >> 48) & 0xffff;
89  case VK_PPC_HIGHESTA:
90  return ((Value + 0x8000) >> 48) & 0xffff;
91  case VK_PPC_None:
92  break;
93  }
94  llvm_unreachable("Invalid kind!");
95 }
96 
97 bool
99  const MCAsmLayout *Layout,
100  const MCFixup *Fixup) const {
101  MCValue Value;
102 
103  if (!getSubExpr()->evaluateAsRelocatable(Value, Layout, Fixup))
104  return false;
105 
106  if (Value.isAbsolute()) {
107  int64_t Result = evaluateAsInt64(Value.getConstant());
108  if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) &&
109  (Result >= 0x8000))
110  return false;
111  Res = MCValue::get(Result);
112  } else {
113  if (!Layout)
114  return false;
115 
116  MCContext &Context = Layout->getAssembler().getContext();
117  const MCSymbolRefExpr *Sym = Value.getSymA();
118  MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
119  if (Modifier != MCSymbolRefExpr::VK_None)
120  return false;
121  switch (Kind) {
122  default:
123  llvm_unreachable("Invalid kind!");
124  case VK_PPC_LO:
125  Modifier = MCSymbolRefExpr::VK_PPC_LO;
126  break;
127  case VK_PPC_HI:
128  Modifier = MCSymbolRefExpr::VK_PPC_HI;
129  break;
130  case VK_PPC_HA:
131  Modifier = MCSymbolRefExpr::VK_PPC_HA;
132  break;
133  case VK_PPC_HIGH:
134  Modifier = MCSymbolRefExpr::VK_PPC_HIGH;
135  break;
136  case VK_PPC_HIGHA:
138  break;
139  case VK_PPC_HIGHERA:
141  break;
142  case VK_PPC_HIGHER:
144  break;
145  case VK_PPC_HIGHEST:
147  break;
148  case VK_PPC_HIGHESTA:
150  break;
151  }
152  Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
153  Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
154  }
155 
156  return true;
157 }
158 
159 void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
160  Streamer.visitUsedExpr(*getSubExpr());
161 }
LLVMContext & Context
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:321
This class represents lattice values for constants.
Definition: AllocatorList.h:23
This represents an "assembler immediate".
Definition: MCValue.h:39
VariantKind getKind() const
Definition: MCExpr.h:336
static const PPCMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isDarwin, MCContext &Ctx)
Definition: PPCMCExpr.cpp:21
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
Definition: MCValue.h:52
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:73
MCContext & getContext() const
Definition: MCAssembler.h:284
A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like &#39;li&#39; or &#39;addis&#39;.
Definition: PPCFixupKinds.h:33
int64_t getConstant() const
Definition: MCValue.h:46
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:48
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:165
Context object for machine code objects.
Definition: MCContext.h:62
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:644
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:50
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:55
Streaming machine code generation interface.
Definition: MCStreamer.h:188
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
static bool isDarwin(object::Archive::Kind Kind)
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:47
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override
Definition: PPCMCExpr.cpp:26
const MCExpr * getSubExpr() const
getSubExpr - Get the child of this expression.
Definition: PPCMCExpr.h:73
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCSymbol & getSymbol() const
Definition: MCExpr.h:334
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const override
Definition: PPCMCExpr.cpp:98
bool evaluateAsConstant(int64_t &Res) const
Definition: PPCMCExpr.cpp:57
void visitUsedExpr(const MCExpr &Expr)
Definition: MCStreamer.cpp:934
bool isDarwinSyntax() const
isDarwinSyntax - True if expression is to be printed using Darwin syntax.
Definition: PPCMCExpr.h:76
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
Definition: MCValue.h:62
LLVM Value Representation.
Definition: Value.h:72
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
void visitUsedExpr(MCStreamer &Streamer) const override
Definition: PPCMCExpr.cpp:159
MCFixupKind getKind() const
Definition: MCFixup.h:122