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