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 const AVRMCExpr *AVRMCExpr::create(VariantKind Kind, const MCExpr *Expr, 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 72 bool AVRMCExpr::evaluateAsRelocatableImpl(MCValue &Result, 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 86 MCContext &Context = Layout->getAssembler().getContext(); 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) { 104 case AVRMCExpr::VK_AVR_LO8: 105 Value &= 0xff; 106 break; 107 case AVRMCExpr::VK_AVR_HI8: 108 Value &= 0xff00; 109 Value >>= 8; 110 break; 111 case AVRMCExpr::VK_AVR_HH8: 112 Value &= 0xff0000; 113 Value >>= 16; 114 break; 115 case AVRMCExpr::VK_AVR_HHI8: 116 Value &= 0xff000000; 117 Value >>= 24; 118 break; 119 case AVRMCExpr::VK_AVR_PM_LO8: 120 case AVRMCExpr::VK_AVR_LO8_GS: 121 Value >>= 1; // Program memory addresses must always be shifted by one. 122 Value &= 0xff; 123 break; 124 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 Value >>= 8; 129 break; 130 case AVRMCExpr::VK_AVR_PM_HH8: 131 Value >>= 1; // Program memory addresses must always be shifted by one. 132 Value &= 0xff0000; 133 Value >>= 16; 134 break; 135 case AVRMCExpr::VK_AVR_GS: 136 Value >>= 1; // Program memory addresses must always be shifted by one. 137 break; 138 139 case AVRMCExpr::VK_AVR_None: 140 llvm_unreachable("Uninitialized expression."); 141 } 142 return static_cast<uint64_t>(Value) & 0xff; 143 } 144 145 AVR::Fixups AVRMCExpr::getFixupKind() const { 146 AVR::Fixups Kind = AVR::Fixups::LastTargetFixupKind; 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 203 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 if (Modifier != std::end(ModifierNames)) { 209 return Modifier->VariantKind; 210 } 211 return VK_AVR_None; 212 } 213 214 } // end of namespace llvm 215 216