Path: blob/main/contrib/llvm-project/llvm/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
35294 views
//===-- AVRMCExpr.cpp - AVR specific MC expression classes ----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "AVRMCExpr.h"910#include "llvm/MC/MCAssembler.h"11#include "llvm/MC/MCContext.h"12#include "llvm/MC/MCStreamer.h"13#include "llvm/MC/MCValue.h"1415namespace llvm {1617namespace {1819const struct ModifierEntry {20const char *const Spelling;21AVRMCExpr::VariantKind VariantKind;22} ModifierNames[] = {23{"lo8", AVRMCExpr::VK_AVR_LO8}, {"hi8", AVRMCExpr::VK_AVR_HI8},24{"hh8", AVRMCExpr::VK_AVR_HH8}, // synonym with hlo825{"hlo8", AVRMCExpr::VK_AVR_HH8}, {"hhi8", AVRMCExpr::VK_AVR_HHI8},2627{"pm", AVRMCExpr::VK_AVR_PM}, {"pm_lo8", AVRMCExpr::VK_AVR_PM_LO8},28{"pm_hi8", AVRMCExpr::VK_AVR_PM_HI8}, {"pm_hh8", AVRMCExpr::VK_AVR_PM_HH8},2930{"lo8_gs", AVRMCExpr::VK_AVR_LO8_GS}, {"hi8_gs", AVRMCExpr::VK_AVR_HI8_GS},31{"gs", AVRMCExpr::VK_AVR_GS},32};3334} // end of anonymous namespace3536const AVRMCExpr *AVRMCExpr::create(VariantKind Kind, const MCExpr *Expr,37bool Negated, MCContext &Ctx) {38return new (Ctx) AVRMCExpr(Kind, Expr, Negated);39}4041void AVRMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {42assert(Kind != VK_AVR_None);43OS << getName() << '(';44if (isNegated())45OS << '-' << '(';46getSubExpr()->print(OS, MAI);47if (isNegated())48OS << ')';49OS << ')';50}5152bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {53MCValue Value;5455bool isRelocatable =56getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr);5758if (!isRelocatable)59return false;6061if (Value.isAbsolute()) {62Result = evaluateAsInt64(Value.getConstant());63return true;64}6566return false;67}6869bool AVRMCExpr::evaluateAsRelocatableImpl(MCValue &Result,70const MCAssembler *Asm,71const MCFixup *Fixup) const {72MCValue Value;73bool isRelocatable = SubExpr->evaluateAsRelocatable(Value, Asm, Fixup);7475if (!isRelocatable)76return false;7778if (Value.isAbsolute()) {79Result = MCValue::get(evaluateAsInt64(Value.getConstant()));80} else {81if (!Asm || !Asm->hasLayout())82return false;8384MCContext &Context = Asm->getContext();85const MCSymbolRefExpr *Sym = Value.getSymA();86MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();87if (Modifier != MCSymbolRefExpr::VK_None)88return false;89if (Kind == VK_AVR_PM) {90Modifier = MCSymbolRefExpr::VK_AVR_PM;91}9293Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);94Result = MCValue::get(Sym, Value.getSymB(), Value.getConstant());95}9697return true;98}99100int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {101if (Negated)102Value *= -1;103104switch (Kind) {105case AVRMCExpr::VK_AVR_LO8:106Value &= 0xff;107break;108case AVRMCExpr::VK_AVR_HI8:109Value &= 0xff00;110Value >>= 8;111break;112case AVRMCExpr::VK_AVR_HH8:113Value &= 0xff0000;114Value >>= 16;115break;116case AVRMCExpr::VK_AVR_HHI8:117Value &= 0xff000000;118Value >>= 24;119break;120case AVRMCExpr::VK_AVR_PM_LO8:121case AVRMCExpr::VK_AVR_LO8_GS:122Value >>= 1; // Program memory addresses must always be shifted by one.123Value &= 0xff;124break;125case AVRMCExpr::VK_AVR_PM_HI8:126case AVRMCExpr::VK_AVR_HI8_GS:127Value >>= 1; // Program memory addresses must always be shifted by one.128Value &= 0xff00;129Value >>= 8;130break;131case AVRMCExpr::VK_AVR_PM_HH8:132Value >>= 1; // Program memory addresses must always be shifted by one.133Value &= 0xff0000;134Value >>= 16;135break;136case AVRMCExpr::VK_AVR_PM:137case AVRMCExpr::VK_AVR_GS:138Value >>= 1; // Program memory addresses must always be shifted by one.139break;140141case AVRMCExpr::VK_AVR_None:142llvm_unreachable("Uninitialized expression.");143}144return static_cast<uint64_t>(Value) & 0xff;145}146147AVR::Fixups AVRMCExpr::getFixupKind() const {148AVR::Fixups Kind = AVR::Fixups::LastTargetFixupKind;149150switch (getKind()) {151case VK_AVR_LO8:152Kind = isNegated() ? AVR::fixup_lo8_ldi_neg : AVR::fixup_lo8_ldi;153break;154case VK_AVR_HI8:155Kind = isNegated() ? AVR::fixup_hi8_ldi_neg : AVR::fixup_hi8_ldi;156break;157case VK_AVR_HH8:158Kind = isNegated() ? AVR::fixup_hh8_ldi_neg : AVR::fixup_hh8_ldi;159break;160case VK_AVR_HHI8:161Kind = isNegated() ? AVR::fixup_ms8_ldi_neg : AVR::fixup_ms8_ldi;162break;163164case VK_AVR_PM_LO8:165Kind = isNegated() ? AVR::fixup_lo8_ldi_pm_neg : AVR::fixup_lo8_ldi_pm;166break;167case VK_AVR_PM_HI8:168Kind = isNegated() ? AVR::fixup_hi8_ldi_pm_neg : AVR::fixup_hi8_ldi_pm;169break;170case VK_AVR_PM_HH8:171Kind = isNegated() ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm;172break;173case VK_AVR_PM:174case VK_AVR_GS:175Kind = AVR::fixup_16_pm;176break;177case VK_AVR_LO8_GS:178Kind = AVR::fixup_lo8_ldi_gs;179break;180case VK_AVR_HI8_GS:181Kind = AVR::fixup_hi8_ldi_gs;182break;183184case VK_AVR_None:185llvm_unreachable("Uninitialized expression");186}187188return Kind;189}190191void AVRMCExpr::visitUsedExpr(MCStreamer &Streamer) const {192Streamer.visitUsedExpr(*getSubExpr());193}194195const char *AVRMCExpr::getName() const {196const auto &Modifier =197llvm::find_if(ModifierNames, [this](ModifierEntry const &Mod) {198return Mod.VariantKind == Kind;199});200201if (Modifier != std::end(ModifierNames)) {202return Modifier->Spelling;203}204return nullptr;205}206207AVRMCExpr::VariantKind AVRMCExpr::getKindByName(StringRef Name) {208const auto &Modifier =209llvm::find_if(ModifierNames, [&Name](ModifierEntry const &Mod) {210return Mod.Spelling == Name;211});212213if (Modifier != std::end(ModifierNames)) {214return Modifier->VariantKind;215}216return VK_AVR_None;217}218219} // end of namespace llvm220221222