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