brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 0615ec9 Raw
223 lines · cpp
1//===-- AVRMCAsmInfo.cpp - AVR asm properties -----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the declarations of the AVRMCAsmInfo properties.10//11//===----------------------------------------------------------------------===//12 13#include "AVRMCAsmInfo.h"14#include "llvm/MC/MCAssembler.h"15#include "llvm/MC/MCContext.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCValue.h"18#include "llvm/TargetParser/Triple.h"19 20using namespace llvm;21 22AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) {23  CodePointerSize = 2;24  CalleeSaveStackSlotSize = 2;25  CommentString = ";";26  SeparatorString = "$";27  UsesELFSectionDirectiveForBSS = true;28  SupportsDebugInformation = true;29}30 31namespace {32const struct ModifierEntry {33  const char *const Spelling;34  AVRMCExpr::Specifier specifier;35} ModifierNames[] = {36    {"lo8", AVR::S_LO8},       {"hi8", AVR::S_HI8},37    {"hh8", AVR::S_HH8}, // synonym with hlo838    {"hlo8", AVR::S_HH8},      {"hhi8", AVR::S_HHI8},39 40    {"pm", AVR::S_PM},         {"pm_lo8", AVR::S_PM_LO8},41    {"pm_hi8", AVR::S_PM_HI8}, {"pm_hh8", AVR::S_PM_HH8},42 43    {"lo8_gs", AVR::S_LO8_GS}, {"hi8_gs", AVR::S_HI8_GS},44    {"gs", AVR::S_GS},45};46 47} // end of anonymous namespace48 49AVRMCExpr::Specifier AVRMCExpr::parseSpecifier(StringRef Name) {50  const auto &Modifier =51      llvm::find_if(ModifierNames, [&Name](ModifierEntry const &Mod) {52        return Mod.Spelling == Name;53      });54 55  if (Modifier != std::end(ModifierNames)) {56    return Modifier->specifier;57  }58  return AVR::S_AVR_NONE;59}60 61const char *AVRMCExpr::getName() const {62  const auto &Modifier =63      llvm::find_if(ModifierNames, [this](ModifierEntry const &Mod) {64        return Mod.specifier == getSpecifier();65      });66 67  if (Modifier != std::end(ModifierNames)) {68    return Modifier->Spelling;69  }70  return nullptr;71}72 73AVR::Fixups AVRMCExpr::getFixupKind() const {74  AVR::Fixups Kind = AVR::Fixups::LastTargetFixupKind;75 76  switch (getSpecifier()) {77  case AVR::S_LO8:78    Kind = isNegated() ? AVR::fixup_lo8_ldi_neg : AVR::fixup_lo8_ldi;79    break;80  case AVR::S_HI8:81    Kind = isNegated() ? AVR::fixup_hi8_ldi_neg : AVR::fixup_hi8_ldi;82    break;83  case AVR::S_HH8:84    Kind = isNegated() ? AVR::fixup_hh8_ldi_neg : AVR::fixup_hh8_ldi;85    break;86  case AVR::S_HHI8:87    Kind = isNegated() ? AVR::fixup_ms8_ldi_neg : AVR::fixup_ms8_ldi;88    break;89 90  case AVR::S_PM_LO8:91    Kind = isNegated() ? AVR::fixup_lo8_ldi_pm_neg : AVR::fixup_lo8_ldi_pm;92    break;93  case AVR::S_PM_HI8:94    Kind = isNegated() ? AVR::fixup_hi8_ldi_pm_neg : AVR::fixup_hi8_ldi_pm;95    break;96  case AVR::S_PM_HH8:97    Kind = isNegated() ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm;98    break;99  case AVR::S_PM:100  case AVR::S_GS:101    Kind = AVR::fixup_16_pm;102    break;103  case AVR::S_LO8_GS:104    Kind = AVR::fixup_lo8_ldi_gs;105    break;106  case AVR::S_HI8_GS:107    Kind = AVR::fixup_hi8_ldi_gs;108    break;109 110  default:111    llvm_unreachable("Uninitialized expression");112  }113 114  return Kind;115}116 117void AVRMCAsmInfo::printSpecifierExpr(raw_ostream &OS,118                                      const MCSpecifierExpr &Expr) const {119  auto &E = static_cast<const AVRMCExpr &>(Expr);120  assert(E.getSpecifier() != AVR::S_AVR_NONE);121  OS << E.getName() << '(';122  if (E.isNegated())123    OS << '-' << '(';124  printExpr(OS, *E.getSubExpr());125  if (E.isNegated())126    OS << ')';127  OS << ')';128}129 130int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {131  if (Negated)132    Value *= -1;133 134  switch (getSpecifier()) {135  case AVR::S_LO8:136    Value &= 0xff;137    break;138  case AVR::S_HI8:139    Value &= 0xff00;140    Value >>= 8;141    break;142  case AVR::S_HH8:143    Value &= 0xff0000;144    Value >>= 16;145    break;146  case AVR::S_HHI8:147    Value &= 0xff000000;148    Value >>= 24;149    break;150  case AVR::S_PM_LO8:151  case AVR::S_LO8_GS:152    Value >>= 1; // Program memory addresses must always be shifted by one.153    Value &= 0xff;154    break;155  case AVR::S_PM_HI8:156  case AVR::S_HI8_GS:157    Value >>= 1; // Program memory addresses must always be shifted by one.158    Value &= 0xff00;159    Value >>= 8;160    break;161  case AVR::S_PM_HH8:162    Value >>= 1; // Program memory addresses must always be shifted by one.163    Value &= 0xff0000;164    Value >>= 16;165    break;166  case AVR::S_PM:167  case AVR::S_GS:168    Value >>= 1; // Program memory addresses must always be shifted by one.169    break;170 171  case AVR::S_AVR_NONE:172  default:173    llvm_unreachable("Uninitialized expression.");174  }175  return static_cast<uint64_t>(Value) & 0xff;176}177 178// bool AVRMCExpr::evaluateAsRelocatableImpl(MCValue &Result,179//                                           const MCAssembler *Asm) const {180bool AVRMCAsmInfo::evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr,181                                             MCValue &Result,182                                             const MCAssembler *Asm) const {183  auto &E = static_cast<const AVRMCExpr &>(Expr);184  MCValue Value;185  bool isRelocatable = E.getSubExpr()->evaluateAsRelocatable(Value, Asm);186  if (!isRelocatable)187    return false;188 189  if (Value.isAbsolute()) {190    Result = MCValue::get(E.evaluateAsInt64(Value.getConstant()));191  } else {192    if (!Asm || !Asm->hasLayout())193      return false;194 195    auto Spec = AVR::S_None;196    if (Value.getSpecifier())197      return false;198    assert(!Value.getSubSym());199    if (E.getSpecifier() == AVR::S_PM)200      Spec = AVR::S_PM;201 202    // TODO: don't attach specifier to MCSymbolRefExpr.203    Result =204        MCValue::get(Value.getAddSym(), nullptr, Value.getConstant(), Spec);205  }206 207  return true;208}209 210bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {211  MCValue Value;212  bool isRelocatable = getSubExpr()->evaluateAsRelocatable(Value, nullptr);213  if (!isRelocatable)214    return false;215 216  if (Value.isAbsolute()) {217    Result = evaluateAsInt64(Value.getConstant());218    return true;219  }220 221  return false;222}223