LCOV - code coverage report
Current view: top level - lib/Target/AVR/MCTargetDesc - AVRMCExpr.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 82 89 92.1 %
Date: 2018-10-20 13:21:21 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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[] = {
      26             :     {"lo8", AVRMCExpr::VK_AVR_LO8},       {"hi8", AVRMCExpr::VK_AVR_HI8},
      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             : 
      39         101 : const AVRMCExpr *AVRMCExpr::create(VariantKind Kind, const MCExpr *Expr,
      40             :                                    bool Negated, MCContext &Ctx) {
      41         101 :   return new (Ctx) AVRMCExpr(Kind, Expr, Negated);
      42             : }
      43             : 
      44          88 : void AVRMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
      45             :   assert(Kind != VK_AVR_None);
      46             : 
      47          88 :   if (isNegated())
      48             :     OS << '-';
      49             : 
      50          88 :   OS << getName() << '(';
      51          88 :   getSubExpr()->print(OS, MAI);
      52             :   OS << ')';
      53          88 : }
      54             : 
      55          91 : bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {
      56          91 :   MCValue Value;
      57             : 
      58             :   bool isRelocatable =
      59          91 :       getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr);
      60             : 
      61          91 :   if (!isRelocatable)
      62             :     return false;
      63             : 
      64          91 :   if (Value.isAbsolute()) {
      65          20 :     Result = evaluateAsInt64(Value.getConstant());
      66          20 :     return true;
      67             :   }
      68             : 
      69             :   return false;
      70             : }
      71             : 
      72          42 : bool AVRMCExpr::evaluateAsRelocatableImpl(MCValue &Result,
      73             :                                           const MCAsmLayout *Layout,
      74             :                                           const MCFixup *Fixup) const {
      75          42 :   MCValue Value;
      76          42 :   bool isRelocatable = SubExpr->evaluateAsRelocatable(Value, Layout, Fixup);
      77             : 
      78          42 :   if (!isRelocatable)
      79             :     return false;
      80             : 
      81          42 :   if (Value.isAbsolute()) {
      82           0 :     Result = MCValue::get(evaluateAsInt64(Value.getConstant()));
      83             :   } else {
      84          42 :     if (!Layout) return false;
      85             : 
      86          42 :     MCContext &Context = Layout->getAssembler().getContext();
      87             :     const MCSymbolRefExpr *Sym = Value.getSymA();
      88          42 :     MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
      89          42 :     if (Modifier != MCSymbolRefExpr::VK_None)
      90             :       return false;
      91             : 
      92          42 :     Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
      93          42 :     Result = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
      94             :   }
      95             : 
      96             :   return true;
      97             : }
      98             : 
      99          20 : int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {
     100          20 :   if (Negated)
     101           8 :     Value *= -1;
     102             : 
     103          20 :   switch (Kind) {
     104           5 :   case AVRMCExpr::VK_AVR_LO8:
     105           5 :     Value &= 0xff;
     106           5 :     break;
     107           3 :   case AVRMCExpr::VK_AVR_HI8:
     108             :     Value &= 0xff00;
     109           3 :     Value >>= 8;
     110           3 :     break;
     111           4 :   case AVRMCExpr::VK_AVR_HH8:
     112             :     Value &= 0xff0000;
     113           4 :     Value >>= 16;
     114           4 :     break;
     115           2 :   case AVRMCExpr::VK_AVR_HHI8:
     116             :     Value &= 0xff000000;
     117           2 :     Value >>= 24;
     118           2 :     break;
     119           2 :   case AVRMCExpr::VK_AVR_PM_LO8:
     120             :   case AVRMCExpr::VK_AVR_LO8_GS:
     121           2 :     Value >>= 1; // Program memory addresses must always be shifted by one.
     122           2 :     Value &= 0xff;
     123           2 :     break;
     124           2 :   case AVRMCExpr::VK_AVR_PM_HI8:
     125             :   case AVRMCExpr::VK_AVR_HI8_GS:
     126             :     Value >>= 1; // Program memory addresses must always be shifted by one.
     127             :     Value &= 0xff00;
     128           2 :     Value >>= 8;
     129           2 :     break;
     130           2 :   case AVRMCExpr::VK_AVR_PM_HH8:
     131             :     Value >>= 1; // Program memory addresses must always be shifted by one.
     132             :     Value &= 0xff0000;
     133           2 :     Value >>= 16;
     134           2 :     break;
     135           0 :   case AVRMCExpr::VK_AVR_GS:
     136           0 :     Value >>= 1; // Program memory addresses must always be shifted by one.
     137           0 :     break;
     138             : 
     139             :   case AVRMCExpr::VK_AVR_None:
     140             :     llvm_unreachable("Uninitialized expression.");
     141             :   }
     142          20 :   return static_cast<uint64_t>(Value) & 0xff;
     143             : }
     144             : 
     145          71 : AVR::Fixups AVRMCExpr::getFixupKind() const {
     146             :   AVR::Fixups Kind = AVR::Fixups::LastTargetFixupKind;
     147             : 
     148          71 :   switch (getKind()) {
     149           9 :   case VK_AVR_LO8:
     150           9 :     Kind = isNegated() ? AVR::fixup_lo8_ldi_neg : AVR::fixup_lo8_ldi;
     151             :     break;
     152           9 :   case VK_AVR_HI8:
     153           9 :     Kind = isNegated() ? AVR::fixup_hi8_ldi_neg : AVR::fixup_hi8_ldi;
     154             :     break;
     155          16 :   case VK_AVR_HH8:
     156          16 :     Kind = isNegated() ? AVR::fixup_hh8_ldi_neg : AVR::fixup_hh8_ldi;
     157             :     break;
     158           8 :   case VK_AVR_HHI8:
     159           8 :     Kind = isNegated() ? AVR::fixup_ms8_ldi_neg : AVR::fixup_ms8_ldi;
     160             :     break;
     161             : 
     162           9 :   case VK_AVR_PM_LO8:
     163           9 :     Kind = isNegated() ? AVR::fixup_lo8_ldi_pm_neg : AVR::fixup_lo8_ldi_pm;
     164             :     break;
     165           9 :   case VK_AVR_PM_HI8:
     166           9 :     Kind = isNegated() ? AVR::fixup_hi8_ldi_pm_neg : AVR::fixup_hi8_ldi_pm;
     167             :     break;
     168           9 :   case VK_AVR_PM_HH8:
     169           9 :     Kind = isNegated() ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm;
     170             :     break;
     171           0 :   case VK_AVR_GS:
     172             :     Kind = AVR::fixup_16_pm;
     173           0 :     break;
     174           1 :   case VK_AVR_LO8_GS:
     175             :     Kind = AVR::fixup_lo8_ldi_gs;
     176           1 :     break;
     177           1 :   case VK_AVR_HI8_GS:
     178             :     Kind = AVR::fixup_hi8_ldi_gs;
     179           1 :     break;
     180             : 
     181             :   case VK_AVR_None:
     182             :     llvm_unreachable("Uninitialized expression");
     183             :   }
     184             : 
     185          71 :   return Kind;
     186             : }
     187             : 
     188          42 : void AVRMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
     189          42 :   Streamer.visitUsedExpr(*getSubExpr());
     190          42 : }
     191             : 
     192          88 : const char *AVRMCExpr::getName() const {
     193             :   const auto &Modifier = std::find_if(
     194             :       std::begin(ModifierNames), std::end(ModifierNames),
     195           0 :       [this](ModifierEntry const &Mod) { return Mod.VariantKind == Kind; });
     196             : 
     197          88 :   if (Modifier != std::end(ModifierNames)) {
     198          88 :     return Modifier->Spelling;
     199             :   }
     200             :   return nullptr;
     201             : }
     202             : 
     203          98 : AVRMCExpr::VariantKind AVRMCExpr::getKindByName(StringRef Name) {
     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          98 :   if (Modifier != std::end(ModifierNames)) {
     209          98 :     return Modifier->VariantKind;
     210             :   }
     211             :   return VK_AVR_None;
     212             : }
     213             : 
     214             : } // end of namespace llvm
     215             : 

Generated by: LCOV version 1.13