LLVM  7.0.0svn
AVRMCExpr.cpp
Go to the documentation of this file.
1 //===-- AVRMCExpr.cpp - AVR 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 "AVRMCExpr.h"
11 
12 #include "llvm/MC/MCAsmLayout.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCStreamer.h"
16 #include "llvm/MC/MCValue.h"
17 
18 namespace llvm {
19 
20 namespace {
21 
22 const struct ModifierEntry {
23  const char * const Spelling;
24  AVRMCExpr::VariantKind VariantKind;
25 } ModifierNames[] = {
27  {"hh8", AVRMCExpr::VK_AVR_HH8}, // synonym with hlo8
28  {"hlo8", AVRMCExpr::VK_AVR_HH8}, {"hhi8", AVRMCExpr::VK_AVR_HHI8},
29 
30  {"pm_lo8", AVRMCExpr::VK_AVR_PM_LO8}, {"pm_hi8", AVRMCExpr::VK_AVR_PM_HI8},
31  {"pm_hh8", AVRMCExpr::VK_AVR_PM_HH8},
32 
33  {"lo8_gs", AVRMCExpr::VK_AVR_LO8_GS}, {"hi8_gs", AVRMCExpr::VK_AVR_HI8_GS},
34  {"gs", AVRMCExpr::VK_AVR_GS},
35 };
36 
37 } // end of anonymous namespace
38 
40  bool Negated, MCContext &Ctx) {
41  return new (Ctx) AVRMCExpr(Kind, Expr, Negated);
42 }
43 
44 void AVRMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
45  assert(Kind != VK_AVR_None);
46 
47  if (isNegated())
48  OS << '-';
49 
50  OS << getName() << '(';
51  getSubExpr()->print(OS, MAI);
52  OS << ')';
53 }
54 
55 bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {
56  MCValue Value;
57 
58  bool isRelocatable =
59  getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr);
60 
61  if (!isRelocatable)
62  return false;
63 
64  if (Value.isAbsolute()) {
65  Result = evaluateAsInt64(Value.getConstant());
66  return true;
67  }
68 
69  return false;
70 }
71 
73  const MCAsmLayout *Layout,
74  const MCFixup *Fixup) const {
75  MCValue Value;
76  bool isRelocatable = SubExpr->evaluateAsRelocatable(Value, Layout, Fixup);
77 
78  if (!isRelocatable)
79  return false;
80 
81  if (Value.isAbsolute()) {
82  Result = MCValue::get(evaluateAsInt64(Value.getConstant()));
83  } else {
84  if (!Layout) return false;
85 
87  const MCSymbolRefExpr *Sym = Value.getSymA();
88  MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
89  if (Modifier != MCSymbolRefExpr::VK_None)
90  return false;
91 
92  Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
93  Result = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
94  }
95 
96  return true;
97 }
98 
99 int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {
100  if (Negated)
101  Value *= -1;
102 
103  switch (Kind) {
105  Value &= 0xff;
106  break;
108  Value &= 0xff00;
109  Value >>= 8;
110  break;
112  Value &= 0xff0000;
113  Value >>= 16;
114  break;
116  Value &= 0xff000000;
117  Value >>= 24;
118  break;
121  Value >>= 1; // Program memory addresses must always be shifted by one.
122  Value &= 0xff;
123  break;
126  Value >>= 1; // Program memory addresses must always be shifted by one.
127  Value &= 0xff00;
128  Value >>= 8;
129  break;
131  Value >>= 1; // Program memory addresses must always be shifted by one.
132  Value &= 0xff0000;
133  Value >>= 16;
134  break;
136  Value >>= 1; // Program memory addresses must always be shifted by one.
137  break;
138 
140  llvm_unreachable("Uninitialized expression.");
141  }
142  return static_cast<uint64_t>(Value) & 0xff;
143 }
144 
147 
148  switch (getKind()) {
149  case VK_AVR_LO8:
150  Kind = isNegated() ? AVR::fixup_lo8_ldi_neg : AVR::fixup_lo8_ldi;
151  break;
152  case VK_AVR_HI8:
153  Kind = isNegated() ? AVR::fixup_hi8_ldi_neg : AVR::fixup_hi8_ldi;
154  break;
155  case VK_AVR_HH8:
156  Kind = isNegated() ? AVR::fixup_hh8_ldi_neg : AVR::fixup_hh8_ldi;
157  break;
158  case VK_AVR_HHI8:
159  Kind = isNegated() ? AVR::fixup_ms8_ldi_neg : AVR::fixup_ms8_ldi;
160  break;
161 
162  case VK_AVR_PM_LO8:
163  Kind = isNegated() ? AVR::fixup_lo8_ldi_pm_neg : AVR::fixup_lo8_ldi_pm;
164  break;
165  case VK_AVR_PM_HI8:
166  Kind = isNegated() ? AVR::fixup_hi8_ldi_pm_neg : AVR::fixup_hi8_ldi_pm;
167  break;
168  case VK_AVR_PM_HH8:
169  Kind = isNegated() ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm;
170  break;
171  case VK_AVR_GS:
172  Kind = AVR::fixup_16_pm;
173  break;
174  case VK_AVR_LO8_GS:
175  Kind = AVR::fixup_lo8_ldi_gs;
176  break;
177  case VK_AVR_HI8_GS:
178  Kind = AVR::fixup_hi8_ldi_gs;
179  break;
180 
181  case VK_AVR_None:
182  llvm_unreachable("Uninitialized expression");
183  }
184 
185  return Kind;
186 }
187 
188 void AVRMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
189  Streamer.visitUsedExpr(*getSubExpr());
190 }
191 
192 const char *AVRMCExpr::getName() const {
193  const auto &Modifier = std::find_if(
194  std::begin(ModifierNames), std::end(ModifierNames),
195  [this](ModifierEntry const &Mod) { return Mod.VariantKind == Kind; });
196 
197  if (Modifier != std::end(ModifierNames)) {
198  return Modifier->Spelling;
199  }
200  return nullptr;
201 }
202 
204  const auto &Modifier = std::find_if(
205  std::begin(ModifierNames), std::end(ModifierNames),
206  [&Name](ModifierEntry const &Mod) { return Mod.Spelling == Name; });
207 
208  if (Modifier != std::end(ModifierNames)) {
209  return Modifier->VariantKind;
210  }
211  return VK_AVR_None;
212 }
213 
214 } // end of namespace llvm
215 
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:250
LLVMContext & Context
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:241
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:70
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:321
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
This represents an "assembler immediate".
Definition: MCValue.h:40
VariantKind getKind() const
Definition: MCExpr.h:336
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a 16-bit progra...
Definition: AVRFixupKinds.h:80
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:97
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
Definition: MCValue.h:53
Corresponds to gs().
Definition: AVRMCExpr.h:37
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:67
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:74
void visitUsedExpr(MCStreamer &streamer) const override
Definition: AVRMCExpr.cpp:188
MCContext & getContext() const
Definition: MCAssembler.h:278
int64_t getConstant() const
Definition: MCValue.h:47
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:49
VariantKind
Specifies the type of an expression.
Definition: AVRMCExpr.h:23
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
A expression in AVR machine code.
Definition: AVRMCExpr.h:20
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated negat...
Definition: AVRFixupKinds.h:76
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a 16-bit value ...
Definition: AVRFixupKinds.h:54
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
static StringRef getName(Value *V)
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:166
Context object for machine code objects.
Definition: MCContext.h:63
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override
Definition: AVRMCExpr.cpp:44
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated negat...
Definition: AVRFixupKinds.h:73
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:51
AVR::Fixups getFixupKind() const
Gets the fixup which corresponds to the expression.
Definition: AVRMCExpr.cpp:145
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:183
Corresponds to hlo8() and hh8().
Definition: AVRMCExpr.h:28
Corresponds to pm_lo8().
Definition: AVRMCExpr.h:31
bool evaluateAsConstant(int64_t &Result) const
Evaluates the fixup as a constant value.
Definition: AVRMCExpr.cpp:55
const char * getName() const
Gets the name of the expression.
Definition: AVRMCExpr.cpp:192
Corresponds to lo8(gs()).
Definition: AVRMCExpr.h:35
Corresponds to hi8().
Definition: AVRMCExpr.h:26
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:48
A 16-bit program memory address.
Definition: AVRFixupKinds.h:47
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 16-bit progra...
Definition: AVRFixupKinds.h:84
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:936
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Corresponds to pm_hh8().
Definition: AVRMCExpr.h:33
Corresponds to hi8(gs()).
Definition: AVRMCExpr.h:36
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 24-bi...
const MCSymbol & getSymbol() const
Definition: MCExpr.h:334
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 16-bit value ...
Definition: AVRFixupKinds.h:57
Fixups
The set of supported fixups.
Definition: AVRFixupKinds.h:27
The access may modify the value stored in memory.
void visitUsedExpr(const MCExpr &Expr)
Definition: MCStreamer.cpp:866
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const override
Definition: AVRMCExpr.cpp:72
Corresponds to pm_hi8().
Definition: AVRMCExpr.h:32
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:93
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 32-bit value ...
Definition: AVRFixupKinds.h:63
Corresponds to lo8().
Definition: AVRMCExpr.h:27
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
Definition: MCValue.h:63
static const AVRMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isNegated, MCContext &Ctx)
Creates an AVR machine code expression.
Definition: AVRMCExpr.cpp:39
static VariantKind getKindByName(StringRef Name)
Definition: AVRMCExpr.cpp:203
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 24-bit progra...
Definition: AVRFixupKinds.h:88
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Corresponds to hhi8().
Definition: AVRMCExpr.h:29
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 24-bit value ...
Definition: AVRFixupKinds.h:60