Imported Upstream version 5.18.0.234

Former-commit-id: 8071ec1a8c5eaa9be24b41745add19297608001f
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-01-08 08:22:36 +00:00
parent f32dbaf0b2
commit 212f6bafcb
28494 changed files with 359 additions and 3867025 deletions

View File

@ -1,486 +0,0 @@
//===-- AVRAsmBackend.cpp - AVR Asm Backend ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the AVRAsmBackend class.
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/AVRAsmBackend.h"
#include "MCTargetDesc/AVRFixupKinds.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
// FIXME: we should be doing checks to make sure asm operands
// are not out of bounds.
namespace adjust {
using namespace llvm;
void signed_width(unsigned Width, uint64_t Value, std::string Description,
const MCFixup &Fixup, MCContext *Ctx = nullptr) {
if (!isIntN(Width, Value)) {
std::string Diagnostic = "out of range " + Description;
int64_t Min = minIntN(Width);
int64_t Max = maxIntN(Width);
Diagnostic += " (expected an integer in the range " + std::to_string(Min) +
" to " + std::to_string(Max) + ")";
if (Ctx) {
Ctx->reportFatalError(Fixup.getLoc(), Diagnostic);
} else {
llvm_unreachable(Diagnostic.c_str());
}
}
}
void unsigned_width(unsigned Width, uint64_t Value, std::string Description,
const MCFixup &Fixup, MCContext *Ctx = nullptr) {
if (!isUIntN(Width, Value)) {
std::string Diagnostic = "out of range " + Description;
int64_t Max = maxUIntN(Width);
Diagnostic += " (expected an integer in the range 0 to " +
std::to_string(Max) + ")";
if (Ctx) {
Ctx->reportFatalError(Fixup.getLoc(), Diagnostic);
} else {
llvm_unreachable(Diagnostic.c_str());
}
}
}
/// Adjusts the value of a branch target before fixup application.
void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
// We have one extra bit of precision because the value is rightshifted by
// one.
unsigned_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
// Rightshifts the value by one.
AVR::fixups::adjustBranchTarget(Value);
}
/// Adjusts the value of a relative branch target before fixup application.
void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
// We have one extra bit of precision because the value is rightshifted by
// one.
signed_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
Value -= 2;
// Rightshifts the value by one.
AVR::fixups::adjustBranchTarget(Value);
}
/// 22-bit absolute fixup.
///
/// Resolves to:
/// 1001 kkkk 010k kkkk kkkk kkkk 111k kkkk
///
/// Offset of 0 (so the result is left shifted by 3 bits before application).
void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
adjustBranch(Size, Fixup, Value, Ctx);
auto top = Value & (0xf00000 << 6); // the top four bits
auto middle = Value & (0x1ffff << 5); // the middle 13 bits
auto bottom = Value & 0x1f; // end bottom 5 bits
Value = (top << 6) | (middle << 3) | (bottom << 0);
}
/// 7-bit PC-relative fixup.
///
/// Resolves to:
/// 0000 00kk kkkk k000
/// Offset of 0 (so the result is left shifted by 3 bits before application).
void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
adjustRelativeBranch(Size, Fixup, Value, Ctx);
// Because the value may be negative, we must mask out the sign bits
Value &= 0x7f;
}
/// 12-bit PC-relative fixup.
/// Yes, the fixup is 12 bits even though the name says otherwise.
///
/// Resolves to:
/// 0000 kkkk kkkk kkkk
/// Offset of 0 (so the result isn't left-shifted before application).
void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
adjustRelativeBranch(Size, Fixup, Value, Ctx);
// Because the value may be negative, we must mask out the sign bits
Value &= 0xfff;
}
/// 6-bit fixup for the immediate operand of the ADIW family of
/// instructions.
///
/// Resolves to:
/// 0000 0000 kk00 kkkk
void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x30) << 2) | (Value & 0x0f);
}
/// 5-bit port number fixup on the SBIC family of instructions.
///
/// Resolves to:
/// 0000 0000 AAAA A000
void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
Value &= 0x1f;
Value <<= 3;
}
/// 6-bit port number fixup on the `IN` family of instructions.
///
/// Resolves to:
/// 1011 0AAd dddd AAAA
void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
unsigned_width(6, Value, std::string("port number"), Fixup, Ctx);
Value = ((Value & 0x30) << 5) | (Value & 0x0f);
}
/// Adjusts a program memory address.
/// This is a simple right-shift.
void pm(uint64_t &Value) {
Value >>= 1;
}
/// Fixups relating to the LDI instruction.
namespace ldi {
/// Adjusts a value to fix up the immediate of an `LDI Rd, K` instruction.
///
/// Resolves to:
/// 0000 KKKK 0000 KKKK
/// Offset of 0 (so the result isn't left-shifted before application).
void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
uint64_t upper = Value & 0xf0;
uint64_t lower = Value & 0x0f;
Value = (upper << 4) | lower;
}
void neg(uint64_t &Value) { Value *= -1; }
void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
Value &= 0xff;
ldi::fixup(Size, Fixup, Value, Ctx);
}
void hi8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
Value = (Value & 0xff00) >> 8;
ldi::fixup(Size, Fixup, Value, Ctx);
}
void hh8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
Value = (Value & 0xff0000) >> 16;
ldi::fixup(Size, Fixup, Value, Ctx);
}
void ms8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx = nullptr) {
Value = (Value & 0xff000000) >> 24;
ldi::fixup(Size, Fixup, Value, Ctx);
}
} // end of ldi namespace
} // end of adjust namespace
namespace llvm {
// Prepare value for the target space for it
void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
const MCValue &Target,
uint64_t &Value,
MCContext *Ctx) const {
// The size of the fixup in bits.
uint64_t Size = AVRAsmBackend::getFixupKindInfo(Fixup.getKind()).TargetSize;
unsigned Kind = Fixup.getKind();
// Parsed LLVM-generated temporary labels are already
// adjusted for instruction size, but normal labels aren't.
//
// To handle both cases, we simply un-adjust the temporary label
// case so it acts like all other labels.
if (const MCSymbolRefExpr *A = Target.getSymA()) {
if (A->getSymbol().isTemporary())
Value += 2;
}
switch (Kind) {
default:
llvm_unreachable("unhandled fixup");
case AVR::fixup_7_pcrel:
adjust::fixup_7_pcrel(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_13_pcrel:
adjust::fixup_13_pcrel(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_call:
adjust::fixup_call(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_ldi:
adjust::ldi::fixup(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_lo8_ldi:
adjust::ldi::lo8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_lo8_ldi_pm:
case AVR::fixup_lo8_ldi_gs:
adjust::pm(Value);
adjust::ldi::lo8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_hi8_ldi:
adjust::ldi::hi8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_hi8_ldi_pm:
case AVR::fixup_hi8_ldi_gs:
adjust::pm(Value);
adjust::ldi::hi8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_hh8_ldi:
case AVR::fixup_hh8_ldi_pm:
if (Kind == AVR::fixup_hh8_ldi_pm) adjust::pm(Value);
adjust::ldi::hh8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_ms8_ldi:
adjust::ldi::ms8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_lo8_ldi_neg:
case AVR::fixup_lo8_ldi_pm_neg:
if (Kind == AVR::fixup_lo8_ldi_pm_neg) adjust::pm(Value);
adjust::ldi::neg(Value);
adjust::ldi::lo8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_hi8_ldi_neg:
case AVR::fixup_hi8_ldi_pm_neg:
if (Kind == AVR::fixup_hi8_ldi_pm_neg) adjust::pm(Value);
adjust::ldi::neg(Value);
adjust::ldi::hi8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_hh8_ldi_neg:
case AVR::fixup_hh8_ldi_pm_neg:
if (Kind == AVR::fixup_hh8_ldi_pm_neg) adjust::pm(Value);
adjust::ldi::neg(Value);
adjust::ldi::hh8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_ms8_ldi_neg:
adjust::ldi::neg(Value);
adjust::ldi::ms8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_16:
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
Value &= 0xffff;
break;
case AVR::fixup_16_pm:
Value >>= 1; // Flash addresses are always shifted.
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
Value &= 0xffff;
break;
case AVR::fixup_6_adiw:
adjust::fixup_6_adiw(Fixup, Value, Ctx);
break;
case AVR::fixup_port5:
adjust::fixup_port5(Fixup, Value, Ctx);
break;
case AVR::fixup_port6:
adjust::fixup_port6(Fixup, Value, Ctx);
break;
// Fixups which do not require adjustments.
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
case FK_Data_8:
break;
case FK_GPRel_4:
llvm_unreachable("don't know how to adjust this fixup");
break;
}
}
std::unique_ptr<MCObjectWriter>
AVRAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
return createAVRELFObjectWriter(OS,
MCELFObjectTargetWriter::getOSABI(OSType));
}
void AVRAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
uint64_t Value, bool IsPCRel) const {
adjustFixupValue(Fixup, Target, Value, &Asm.getContext());
if (Value == 0)
return; // Doesn't change encoding.
MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
// The number of bits in the fixup mask
auto NumBits = Info.TargetSize + Info.TargetOffset;
auto NumBytes = (NumBits / 8) + ((NumBits % 8) == 0 ? 0 : 1);
// Shift the value into position.
Value <<= Info.TargetOffset;
unsigned Offset = Fixup.getOffset();
assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
// For each byte of the fragment that the fixup touches, mask in the
// bits from the fixup value.
for (unsigned i = 0; i < NumBytes; ++i) {
uint8_t mask = (((Value >> (i * 8)) & 0xff));
Data[Offset + i] |= mask;
}
}
MCFixupKindInfo const &AVRAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
// NOTE: Many AVR fixups work on sets of non-contignous bits. We work around
// this by saying that the fixup is the size of the entire instruction.
const static MCFixupKindInfo Infos[AVR::NumTargetFixupKinds] = {
// This table *must* be in same the order of fixup_* kinds in
// AVRFixupKinds.h.
//
// name offset bits flags
{"fixup_32", 0, 32, 0},
{"fixup_7_pcrel", 3, 7, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_13_pcrel", 0, 12, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_16", 0, 16, 0},
{"fixup_16_pm", 0, 16, 0},
{"fixup_ldi", 0, 8, 0},
{"fixup_lo8_ldi", 0, 8, 0},
{"fixup_hi8_ldi", 0, 8, 0},
{"fixup_hh8_ldi", 0, 8, 0},
{"fixup_ms8_ldi", 0, 8, 0},
{"fixup_lo8_ldi_neg", 0, 8, 0},
{"fixup_hi8_ldi_neg", 0, 8, 0},
{"fixup_hh8_ldi_neg", 0, 8, 0},
{"fixup_ms8_ldi_neg", 0, 8, 0},
{"fixup_lo8_ldi_pm", 0, 8, 0},
{"fixup_hi8_ldi_pm", 0, 8, 0},
{"fixup_hh8_ldi_pm", 0, 8, 0},
{"fixup_lo8_ldi_pm_neg", 0, 8, 0},
{"fixup_hi8_ldi_pm_neg", 0, 8, 0},
{"fixup_hh8_ldi_pm_neg", 0, 8, 0},
{"fixup_call", 0, 22, 0},
{"fixup_6", 0, 16, 0}, // non-contiguous
{"fixup_6_adiw", 0, 6, 0},
{"fixup_lo8_ldi_gs", 0, 8, 0},
{"fixup_hi8_ldi_gs", 0, 8, 0},
{"fixup_8", 0, 8, 0},
{"fixup_8_lo8", 0, 8, 0},
{"fixup_8_hi8", 0, 8, 0},
{"fixup_8_hlo8", 0, 8, 0},
{"fixup_diff8", 0, 8, 0},
{"fixup_diff16", 0, 16, 0},
{"fixup_diff32", 0, 32, 0},
{"fixup_lds_sts_16", 0, 16, 0},
{"fixup_port6", 0, 16, 0}, // non-contiguous
{"fixup_port5", 3, 5, 0},
};
if (Kind < FirstTargetFixupKind)
return MCAsmBackend::getFixupKindInfo(Kind);
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
return Infos[Kind - FirstTargetFixupKind];
}
bool AVRAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
// If the count is not 2-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
assert((Count % 2) == 0 && "NOP instructions must be 2 bytes");
OW->WriteZeros(Count);
return true;
}
bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target) {
switch ((unsigned) Fixup.getKind()) {
default: return false;
// Fixups which should always be recorded as relocations.
case AVR::fixup_7_pcrel:
case AVR::fixup_13_pcrel:
case AVR::fixup_call:
return true;
}
}
MCAsmBackend *createAVRAsmBackend(const Target &T, const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const llvm::MCTargetOptions &TO) {
return new AVRAsmBackend(STI.getTargetTriple().getOS());
}
} // end of namespace llvm

View File

@ -1,77 +0,0 @@
//===-- AVRAsmBackend.h - AVR Asm Backend --------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// \file The AVR assembly backend implementation.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_AVR_ASM_BACKEND_H
#define LLVM_AVR_ASM_BACKEND_H
#include "MCTargetDesc/AVRFixupKinds.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCAsmBackend.h"
namespace llvm {
class MCAssembler;
class MCObjectWriter;
class Target;
struct MCFixupKindInfo;
/// Utilities for manipulating generated AVR machine code.
class AVRAsmBackend : public MCAsmBackend {
public:
AVRAsmBackend(Triple::OSType OSType)
: MCAsmBackend(), OSType(OSType) {}
void adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
uint64_t &Value, MCContext *Ctx = nullptr) const;
std::unique_ptr<MCObjectWriter> createObjectWriter(raw_pwrite_stream &OS) const override;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
uint64_t Value, bool IsPCRel) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
unsigned getNumFixupKinds() const override {
return AVR::NumTargetFixupKinds;
}
bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const override {
llvm_unreachable("RelaxInstruction() unimplemented");
return false;
}
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override {}
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target) override;
private:
Triple::OSType OSType;
};
} // end namespace llvm
#endif // LLVM_AVR_ASM_BACKEND_H

View File

@ -1,162 +0,0 @@
//===-- AVRELFObjectWriter.cpp - AVR ELF Writer ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/AVRFixupKinds.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
/// Writes AVR machine code into an ELF32 object file.
class AVRELFObjectWriter : public MCELFObjectTargetWriter {
public:
AVRELFObjectWriter(uint8_t OSABI);
virtual ~AVRELFObjectWriter() {}
unsigned getRelocType(MCContext &Ctx,
const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const override;
};
AVRELFObjectWriter::AVRELFObjectWriter(uint8_t OSABI)
: MCELFObjectTargetWriter(false, OSABI, ELF::EM_AVR, true) {}
unsigned AVRELFObjectWriter::getRelocType(MCContext &Ctx,
const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
switch ((unsigned) Fixup.getKind()) {
case FK_Data_1:
switch (Modifier) {
default:
llvm_unreachable("Unsupported Modifier");
case MCSymbolRefExpr::VK_None:
return ELF::R_AVR_8;
case MCSymbolRefExpr::VK_AVR_DIFF8:
return ELF::R_AVR_DIFF8;
case MCSymbolRefExpr::VK_AVR_LO8:
return ELF::R_AVR_8_LO8;
case MCSymbolRefExpr::VK_AVR_HI8:
return ELF::R_AVR_8_HI8;
case MCSymbolRefExpr::VK_AVR_HLO8:
return ELF::R_AVR_8_HLO8;
}
case FK_Data_4:
switch (Modifier) {
default:
llvm_unreachable("Unsupported Modifier");
case MCSymbolRefExpr::VK_None:
return ELF::R_AVR_32;
case MCSymbolRefExpr::VK_AVR_DIFF32:
return ELF::R_AVR_DIFF32;
}
case FK_Data_2:
switch (Modifier) {
default:
llvm_unreachable("Unsupported Modifier");
case MCSymbolRefExpr::VK_None:
return ELF::R_AVR_16;
case MCSymbolRefExpr::VK_AVR_NONE:
return ELF::R_AVR_16_PM;
case MCSymbolRefExpr::VK_AVR_DIFF16:
return ELF::R_AVR_DIFF16;
}
case AVR::fixup_32:
return ELF::R_AVR_32;
case AVR::fixup_7_pcrel:
return ELF::R_AVR_7_PCREL;
case AVR::fixup_13_pcrel:
return ELF::R_AVR_13_PCREL;
case AVR::fixup_16:
return ELF::R_AVR_16;
case AVR::fixup_16_pm:
return ELF::R_AVR_16_PM;
case AVR::fixup_lo8_ldi:
return ELF::R_AVR_LO8_LDI;
case AVR::fixup_hi8_ldi:
return ELF::R_AVR_HI8_LDI;
case AVR::fixup_hh8_ldi:
return ELF::R_AVR_HH8_LDI;
case AVR::fixup_lo8_ldi_neg:
return ELF::R_AVR_LO8_LDI_NEG;
case AVR::fixup_hi8_ldi_neg:
return ELF::R_AVR_HI8_LDI_NEG;
case AVR::fixup_hh8_ldi_neg:
return ELF::R_AVR_HH8_LDI_NEG;
case AVR::fixup_lo8_ldi_pm:
return ELF::R_AVR_LO8_LDI_PM;
case AVR::fixup_hi8_ldi_pm:
return ELF::R_AVR_HI8_LDI_PM;
case AVR::fixup_hh8_ldi_pm:
return ELF::R_AVR_HH8_LDI_PM;
case AVR::fixup_lo8_ldi_pm_neg:
return ELF::R_AVR_LO8_LDI_PM_NEG;
case AVR::fixup_hi8_ldi_pm_neg:
return ELF::R_AVR_HI8_LDI_PM_NEG;
case AVR::fixup_hh8_ldi_pm_neg:
return ELF::R_AVR_HH8_LDI_PM_NEG;
case AVR::fixup_call:
return ELF::R_AVR_CALL;
case AVR::fixup_ldi:
return ELF::R_AVR_LDI;
case AVR::fixup_6:
return ELF::R_AVR_6;
case AVR::fixup_6_adiw:
return ELF::R_AVR_6_ADIW;
case AVR::fixup_ms8_ldi:
return ELF::R_AVR_MS8_LDI;
case AVR::fixup_ms8_ldi_neg:
return ELF::R_AVR_MS8_LDI_NEG;
case AVR::fixup_lo8_ldi_gs:
return ELF::R_AVR_LO8_LDI_GS;
case AVR::fixup_hi8_ldi_gs:
return ELF::R_AVR_HI8_LDI_GS;
case AVR::fixup_8:
return ELF::R_AVR_8;
case AVR::fixup_8_lo8:
return ELF::R_AVR_8_LO8;
case AVR::fixup_8_hi8:
return ELF::R_AVR_8_HI8;
case AVR::fixup_8_hlo8:
return ELF::R_AVR_8_HLO8;
case AVR::fixup_diff8:
return ELF::R_AVR_DIFF8;
case AVR::fixup_diff16:
return ELF::R_AVR_DIFF16;
case AVR::fixup_diff32:
return ELF::R_AVR_DIFF32;
case AVR::fixup_lds_sts_16:
return ELF::R_AVR_LDS_STS_16;
case AVR::fixup_port6:
return ELF::R_AVR_PORT6;
case AVR::fixup_port5:
return ELF::R_AVR_PORT5;
default:
llvm_unreachable("invalid fixup kind!");
}
}
std::unique_ptr<MCObjectWriter>
createAVRELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI) {
std::unique_ptr<MCELFObjectTargetWriter> MOTW(new AVRELFObjectWriter(OSABI));
return createELFObjectWriter(std::move(MOTW), OS, true);
}
} // end of namespace llvm

View File

@ -1,68 +0,0 @@
#include "AVRELFStreamer.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/FormattedStream.h"
#include "AVRMCTargetDesc.h"
namespace llvm {
static unsigned getEFlagsForFeatureSet(const FeatureBitset &Features) {
unsigned EFlags = 0;
// Set architecture
if (Features[AVR::ELFArchAVR1])
EFlags |= ELF::EF_AVR_ARCH_AVR1;
else if (Features[AVR::ELFArchAVR2])
EFlags |= ELF::EF_AVR_ARCH_AVR2;
else if (Features[AVR::ELFArchAVR25])
EFlags |= ELF::EF_AVR_ARCH_AVR25;
else if (Features[AVR::ELFArchAVR3])
EFlags |= ELF::EF_AVR_ARCH_AVR3;
else if (Features[AVR::ELFArchAVR31])
EFlags |= ELF::EF_AVR_ARCH_AVR31;
else if (Features[AVR::ELFArchAVR35])
EFlags |= ELF::EF_AVR_ARCH_AVR35;
else if (Features[AVR::ELFArchAVR4])
EFlags |= ELF::EF_AVR_ARCH_AVR4;
else if (Features[AVR::ELFArchAVR5])
EFlags |= ELF::EF_AVR_ARCH_AVR5;
else if (Features[AVR::ELFArchAVR51])
EFlags |= ELF::EF_AVR_ARCH_AVR51;
else if (Features[AVR::ELFArchAVR6])
EFlags |= ELF::EF_AVR_ARCH_AVR6;
else if (Features[AVR::ELFArchTiny])
EFlags |= ELF::EF_AVR_ARCH_AVRTINY;
else if (Features[AVR::ELFArchXMEGA1])
EFlags |= ELF::EF_AVR_ARCH_XMEGA1;
else if (Features[AVR::ELFArchXMEGA2])
EFlags |= ELF::EF_AVR_ARCH_XMEGA2;
else if (Features[AVR::ELFArchXMEGA3])
EFlags |= ELF::EF_AVR_ARCH_XMEGA3;
else if (Features[AVR::ELFArchXMEGA4])
EFlags |= ELF::EF_AVR_ARCH_XMEGA4;
else if (Features[AVR::ELFArchXMEGA5])
EFlags |= ELF::EF_AVR_ARCH_XMEGA5;
else if (Features[AVR::ELFArchXMEGA6])
EFlags |= ELF::EF_AVR_ARCH_XMEGA6;
else if (Features[AVR::ELFArchXMEGA7])
EFlags |= ELF::EF_AVR_ARCH_XMEGA7;
return EFlags;
}
AVRELFStreamer::AVRELFStreamer(MCStreamer &S,
const MCSubtargetInfo &STI)
: AVRTargetStreamer(S) {
MCAssembler &MCA = getStreamer().getAssembler();
unsigned EFlags = MCA.getELFHeaderEFlags();
EFlags |= getEFlagsForFeatureSet(STI.getFeatureBits());
MCA.setELFHeaderEFlags(EFlags);
}
} // end namespace llvm

View File

@ -1,29 +0,0 @@
//===----- AVRELFStreamer.h - AVR Target Streamer --------------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_ELF_STREAMER_H
#define LLVM_AVR_ELF_STREAMER_H
#include "AVRTargetStreamer.h"
namespace llvm {
/// A target streamer for an AVR ELF object file.
class AVRELFStreamer : public AVRTargetStreamer {
public:
AVRELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
MCELFStreamer &getStreamer() {
return static_cast<MCELFStreamer &>(Streamer);
}
};
} // end namespace llvm
#endif

View File

@ -1,148 +0,0 @@
//===-- AVRFixupKinds.h - AVR Specific Fixup Entries ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_FIXUP_KINDS_H
#define LLVM_AVR_FIXUP_KINDS_H
#include "llvm/MC/MCFixup.h"
namespace llvm {
namespace AVR {
/// The set of supported fixups.
///
/// Although most of the current fixup types reflect a unique relocation
/// one can have multiple fixup types for a given relocation and thus need
/// to be uniquely named.
///
/// \note This table *must* be in the same order of
/// MCFixupKindInfo Infos[AVR::NumTargetFixupKinds]
/// in `AVRAsmBackend.cpp`.
enum Fixups {
/// A 32-bit AVR fixup.
fixup_32 = FirstTargetFixupKind,
/// A 7-bit PC-relative fixup for the family of conditional
/// branches which take 7-bit targets (BRNE,BRGT,etc).
fixup_7_pcrel,
/// A 12-bit PC-relative fixup for the family of branches
/// which take 12-bit targets (RJMP,RCALL,etc).
/// \note Although the fixup is labelled as 13 bits, it
/// is actually only encoded in 12. The reason for
/// The nonmenclature is that AVR branch targets are
/// rightshifted by 1, because instructions are always
/// aligned to 2 bytes, so the 0'th bit is always 0.
/// This way there is 13-bits of precision.
fixup_13_pcrel,
/// A 16-bit address.
fixup_16,
/// A 16-bit program memory address.
fixup_16_pm,
/// Replaces the 8-bit immediate with another value.
fixup_ldi,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the lower 8 bits of a 16-bit value (bits 0-7).
fixup_lo8_ldi,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a 16-bit value (bits 8-15).
fixup_hi8_ldi,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a 24-bit value (bits 16-23).
fixup_hh8_ldi,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a 32-bit value (bits 24-31).
fixup_ms8_ldi,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the lower 8 bits of a negated 16-bit value (bits 0-7).
fixup_lo8_ldi_neg,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a negated 16-bit value (bits 8-15).
fixup_hi8_ldi_neg,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a negated negated 24-bit value (bits 16-23).
fixup_hh8_ldi_neg,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a negated negated 32-bit value (bits 24-31).
fixup_ms8_ldi_neg,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the lower 8 bits of a 16-bit program memory address value (bits 0-7).
fixup_lo8_ldi_pm,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a 16-bit program memory address value (bits
/// 8-15).
fixup_hi8_ldi_pm,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a 24-bit program memory address value (bits
/// 16-23).
fixup_hh8_ldi_pm,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the lower 8 bits of a negated 16-bit program memory address value
/// (bits 0-7).
fixup_lo8_ldi_pm_neg,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a negated 16-bit program memory address value
/// (bits 8-15).
fixup_hi8_ldi_pm_neg,
/// Replaces the immediate operand of a 16-bit `Rd, K` instruction
/// with the upper 8 bits of a negated 24-bit program memory address value
/// (bits 16-23).
fixup_hh8_ldi_pm_neg,
/// A 22-bit fixup for the target of a `CALL k` or `JMP k` instruction.
fixup_call,
fixup_6,
/// A symbol+addr fixup for the `LDD <x>+<n>, <r>" family of instructions.
fixup_6_adiw,
fixup_lo8_ldi_gs,
fixup_hi8_ldi_gs,
fixup_8,
fixup_8_lo8,
fixup_8_hi8,
fixup_8_hlo8,
fixup_diff8,
fixup_diff16,
fixup_diff32,
fixup_lds_sts_16,
/// A 6-bit port address.
fixup_port6,
/// A 5-bit port address.
fixup_port5,
// Marker
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
};
namespace fixups {
/// Adjusts the value of a branch target.
/// All branch targets in AVR are rightshifted by 1 to take advantage
/// of the fact that all instructions are aligned to addresses of size
/// 2, so bit 0 of an address is always 0. This gives us another bit
/// of precision.
/// \param[in,out] The target to adjust.
template <typename T> inline void adjustBranchTarget(T &val) { val >>= 1; }
} // end of namespace fixups
}
} // end of namespace llvm::AVR
#endif // LLVM_AVR_FIXUP_KINDS_H

View File

@ -1,29 +0,0 @@
//===-- AVRMCAsmInfo.cpp - AVR asm properties -----------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the AVRMCAsmInfo properties.
//
//===----------------------------------------------------------------------===//
#include "AVRMCAsmInfo.h"
#include "llvm/ADT/Triple.h"
namespace llvm {
AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT) {
CodePointerSize = 2;
CalleeSaveStackSlotSize = 2;
CommentString = ";";
PrivateGlobalPrefix = ".L";
UsesELFSectionDirectiveForBSS = true;
UseIntegratedAssembler = true;
}
} // end of namespace llvm

View File

@ -1,31 +0,0 @@
//===-- AVRMCAsmInfo.h - AVR asm properties ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the AVRMCAsmInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_ASM_INFO_H
#define LLVM_AVR_ASM_INFO_H
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
class Triple;
/// Specifies the format of AVR assembly files.
class AVRMCAsmInfo : public MCAsmInfo {
public:
explicit AVRMCAsmInfo(const Triple &TT);
};
} // end namespace llvm
#endif // LLVM_AVR_ASM_INFO_H

View File

@ -1,305 +0,0 @@
//===-- AVRMCCodeEmitter.cpp - Convert AVR Code to Machine Code -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the AVRMCCodeEmitter class.
//
//===----------------------------------------------------------------------===//
#include "AVRMCCodeEmitter.h"
#include "MCTargetDesc/AVRMCExpr.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE "mccodeemitter"
#define GET_INSTRMAP_INFO
#include "AVRGenInstrInfo.inc"
#undef GET_INSTRMAP_INFO
namespace llvm {
/// Performs a post-encoding step on a `LD` or `ST` instruction.
///
/// The encoding of the LD/ST family of instructions is inconsistent w.r.t
/// the pointer register and the addressing mode.
///
/// The permutations of the format are as followed:
/// ld Rd, X `1001 000d dddd 1100`
/// ld Rd, X+ `1001 000d dddd 1101`
/// ld Rd, -X `1001 000d dddd 1110`
///
/// ld Rd, Y `1000 000d dddd 1000`
/// ld Rd, Y+ `1001 000d dddd 1001`
/// ld Rd, -Y `1001 000d dddd 1010`
///
/// ld Rd, Z `1000 000d dddd 0000`
/// ld Rd, Z+ `1001 000d dddd 0001`
/// ld Rd, -Z `1001 000d dddd 0010`
/// ^
/// |
/// Note this one inconsistent bit - it is 1 sometimes and 0 at other times.
/// There is no logical pattern. Looking at a truth table, the following
/// formula can be derived to fit the pattern:
//
/// ```
/// inconsistent_bit = is_predec OR is_postinc OR is_reg_x
/// ```
//
/// We manually set this bit in this post encoder method.
unsigned
AVRMCCodeEmitter::loadStorePostEncoder(const MCInst &MI, unsigned EncodedValue,
const MCSubtargetInfo &STI) const {
assert(MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
"the load/store operands must be registers");
unsigned Opcode = MI.getOpcode();
// check whether either of the registers are the X pointer register.
bool IsRegX = MI.getOperand(0).getReg() == AVR::R27R26 ||
MI.getOperand(1).getReg() == AVR::R27R26;
bool IsPredec = Opcode == AVR::LDRdPtrPd || Opcode == AVR::STPtrPdRr;
bool IsPostinc = Opcode == AVR::LDRdPtrPi || Opcode == AVR::STPtrPiRr;
// Check if we need to set the inconsistent bit
if (IsRegX || IsPredec || IsPostinc) {
EncodedValue |= (1 << 12);
}
return EncodedValue;
}
template <AVR::Fixups Fixup>
unsigned
AVRMCCodeEmitter::encodeRelCondBrTarget(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpNo);
if (MO.isExpr()) {
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
MCFixupKind(Fixup), MI.getLoc()));
return 0;
}
assert(MO.isImm());
// Take the size of the current instruction away.
// With labels, this is implicitly done.
auto target = MO.getImm();
AVR::fixups::adjustBranchTarget(target);
return target;
}
unsigned AVRMCCodeEmitter::encodeLDSTPtrReg(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
auto MO = MI.getOperand(OpNo);
// The operand should be a pointer register.
assert(MO.isReg());
switch (MO.getReg()) {
case AVR::R27R26: return 0x03; // X: 0b11
case AVR::R29R28: return 0x02; // Y: 0b10
case AVR::R31R30: return 0x00; // Z: 0b00
default:
llvm_unreachable("invalid pointer register");
}
}
/// Encodes a `memri` operand.
/// The operand is 7-bits.
/// * The lower 6 bits is the immediate
/// * The upper bit is the pointer register bit (Z=0,Y=1)
unsigned AVRMCCodeEmitter::encodeMemri(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
auto RegOp = MI.getOperand(OpNo);
auto OffsetOp = MI.getOperand(OpNo + 1);
assert(RegOp.isReg() && "Expected register operand");
uint8_t RegBit = 0;
switch (RegOp.getReg()) {
default:
llvm_unreachable("Expected either Y or Z register");
case AVR::R31R30:
RegBit = 0;
break; // Z register
case AVR::R29R28:
RegBit = 1;
break; // Y register
}
int8_t OffsetBits;
if (OffsetOp.isImm()) {
OffsetBits = OffsetOp.getImm();
} else if (OffsetOp.isExpr()) {
OffsetBits = 0;
Fixups.push_back(MCFixup::create(0, OffsetOp.getExpr(),
MCFixupKind(AVR::fixup_6), MI.getLoc()));
} else {
llvm_unreachable("invalid value for offset");
}
return (RegBit << 6) | OffsetBits;
}
unsigned AVRMCCodeEmitter::encodeComplement(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
// The operand should be an immediate.
assert(MI.getOperand(OpNo).isImm());
auto Imm = MI.getOperand(OpNo).getImm();
return (~0) - Imm;
}
template <AVR::Fixups Fixup, unsigned Offset>
unsigned AVRMCCodeEmitter::encodeImm(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
auto MO = MI.getOperand(OpNo);
if (MO.isExpr()) {
if (isa<AVRMCExpr>(MO.getExpr())) {
// If the expression is already an AVRMCExpr (i.e. a lo8(symbol),
// we shouldn't perform any more fixups. Without this check, we would
// instead create a fixup to the symbol named 'lo8(symbol)' which
// is not correct.
return getExprOpValue(MO.getExpr(), Fixups, STI);
}
MCFixupKind FixupKind = static_cast<MCFixupKind>(Fixup);
Fixups.push_back(MCFixup::create(Offset, MO.getExpr(), FixupKind, MI.getLoc()));
return 0;
}
assert(MO.isImm());
return MO.getImm();
}
unsigned AVRMCCodeEmitter::encodeCallTarget(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
auto MO = MI.getOperand(OpNo);
if (MO.isExpr()) {
MCFixupKind FixupKind = static_cast<MCFixupKind>(AVR::fixup_call);
Fixups.push_back(MCFixup::create(0, MO.getExpr(), FixupKind, MI.getLoc()));
return 0;
}
assert(MO.isImm());
auto Target = MO.getImm();
AVR::fixups::adjustBranchTarget(Target);
return Target;
}
unsigned AVRMCCodeEmitter::getExprOpValue(const MCExpr *Expr,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
MCExpr::ExprKind Kind = Expr->getKind();
if (Kind == MCExpr::Binary) {
Expr = static_cast<const MCBinaryExpr *>(Expr)->getLHS();
Kind = Expr->getKind();
}
if (Kind == MCExpr::Target) {
AVRMCExpr const *AVRExpr = cast<AVRMCExpr>(Expr);
int64_t Result;
if (AVRExpr->evaluateAsConstant(Result)) {
return Result;
}
MCFixupKind FixupKind = static_cast<MCFixupKind>(AVRExpr->getFixupKind());
Fixups.push_back(MCFixup::create(0, AVRExpr, FixupKind));
return 0;
}
assert(Kind == MCExpr::SymbolRef);
return 0;
}
unsigned AVRMCCodeEmitter::getMachineOpValue(const MCInst &MI,
const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
if (MO.isReg()) return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
if (MO.isImm()) return static_cast<unsigned>(MO.getImm());
if (MO.isFPImm())
return static_cast<unsigned>(APFloat(MO.getFPImm())
.bitcastToAPInt()
.getHiBits(32)
.getLimitedValue());
// MO must be an Expr.
assert(MO.isExpr());
return getExprOpValue(MO.getExpr(), Fixups, STI);
}
void AVRMCCodeEmitter::emitInstruction(uint64_t Val, unsigned Size,
const MCSubtargetInfo &STI,
raw_ostream &OS) const {
const uint16_t *Words = reinterpret_cast<uint16_t const *>(&Val);
size_t WordCount = Size / 2;
for (int64_t i = WordCount - 1; i >= 0; --i) {
uint16_t Word = Words[i];
OS << (uint8_t) ((Word & 0x00ff) >> 0);
OS << (uint8_t) ((Word & 0xff00) >> 8);
}
}
void AVRMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
// Get byte count of instruction
unsigned Size = Desc.getSize();
assert(Size > 0 && "Instruction size cannot be zero");
uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);
emitInstruction(BinaryOpCode, Size, STI, OS);
}
MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
MCContext &Ctx) {
return new AVRMCCodeEmitter(MCII, Ctx);
}
#include "AVRGenMCCodeEmitter.inc"
} // end of namespace llvm

View File

@ -1,116 +0,0 @@
//===-- AVRMCCodeEmitter.h - Convert AVR Code to Machine Code -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the AVRMCCodeEmitter class.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_AVR_CODE_EMITTER_H
#define LLVM_AVR_CODE_EMITTER_H
#include "AVRFixupKinds.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/Support/DataTypes.h"
#define GET_INSTRINFO_OPERAND_TYPES_ENUM
#include "AVRGenInstrInfo.inc"
namespace llvm {
class MCContext;
class MCExpr;
class MCFixup;
class MCInst;
class MCInstrInfo;
class MCOperand;
class MCSubtargetInfo;
class raw_ostream;
/// Writes AVR machine code to a stream.
class AVRMCCodeEmitter : public MCCodeEmitter {
public:
AVRMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
: MCII(MCII), Ctx(Ctx) {}
private:
/// Finishes up encoding an LD/ST instruction.
/// The purpose of this function is to set an bit in the instruction
/// which follows no logical pattern. See the implementation for details.
unsigned loadStorePostEncoder(const MCInst &MI, unsigned EncodedValue,
const MCSubtargetInfo &STI) const;
/// Gets the encoding for a conditional branch target.
template <AVR::Fixups Fixup>
unsigned encodeRelCondBrTarget(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Encodes the `PTRREGS` operand to a load or store instruction.
unsigned encodeLDSTPtrReg(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Encodes a `register+immediate` operand for `LDD`/`STD`.
unsigned encodeMemri(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Takes the complement of a number (~0 - val).
unsigned encodeComplement(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Encodes an immediate value with a given fixup.
/// \tparam Offset The offset into the instruction for the fixup.
template <AVR::Fixups Fixup, unsigned Offset>
unsigned encodeImm(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Gets the encoding of the target for the `CALL k` instruction.
unsigned encodeCallTarget(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// TableGen'ed function to get the binary encoding for an instruction.
uint64_t getBinaryCodeForInstr(const MCInst &MI,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Returns the binary encoding of operand.
///
/// If the machine operand requires relocation, the relocation is recorded
/// and zero is returned.
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
void emitInstruction(uint64_t Val, unsigned Size, const MCSubtargetInfo &STI,
raw_ostream &OS) const;
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
AVRMCCodeEmitter(const AVRMCCodeEmitter &) = delete;
void operator=(const AVRMCCodeEmitter &) = delete;
const MCInstrInfo &MCII;
MCContext &Ctx;
};
} // end namespace of llvm.
#endif // LLVM_AVR_CODE_EMITTER_H

View File

@ -1,51 +0,0 @@
//===--------- AVRMCELFStreamer.cpp - AVR subclass of MCELFStreamer -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a stub that parses a MCInst bundle and passes the
// instructions on to the real streamer.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "avrmcelfstreamer"
#include "MCTargetDesc/AVRMCELFStreamer.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSymbol.h"
using namespace llvm;
void AVRMCELFStreamer::EmitValueForModiferKind(
const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc,
AVRMCExpr::VariantKind ModifierKind) {
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_AVR_NONE;
if (ModifierKind == AVRMCExpr::VK_AVR_None) {
Kind = MCSymbolRefExpr::VK_AVR_DIFF8;
if (SizeInBytes == SIZE_LONG)
Kind = MCSymbolRefExpr::VK_AVR_DIFF32;
else if (SizeInBytes == SIZE_WORD)
Kind = MCSymbolRefExpr::VK_AVR_DIFF16;
} else if (ModifierKind == AVRMCExpr::VK_AVR_LO8)
Kind = MCSymbolRefExpr::VK_AVR_LO8;
else if (ModifierKind == AVRMCExpr::VK_AVR_HI8)
Kind = MCSymbolRefExpr::VK_AVR_HI8;
else if (ModifierKind == AVRMCExpr::VK_AVR_HH8)
Kind = MCSymbolRefExpr::VK_AVR_HLO8;
MCELFStreamer::EmitValue(MCSymbolRefExpr::create(Sym, Kind, getContext()),
SizeInBytes, Loc);
}
namespace llvm {
MCStreamer *createAVRELFStreamer(Triple const &TT, MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> CE) {
return new AVRMCELFStreamer(Context, std::move(MAB), OS, std::move(CE));
}
} // end namespace llvm

View File

@ -1,54 +0,0 @@
//===--------- AVRMCELFStreamer.h - AVR subclass of MCELFStreamer ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_AVR_MCTARGETDESC_AVRMCELFSTREAMER_H
#define LLVM_LIB_TARGET_AVR_MCTARGETDESC_AVRMCELFSTREAMER_H
#include "MCTargetDesc/AVRMCExpr.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInstrInfo.h"
namespace llvm {
const int SIZE_LONG = 4;
const int SIZE_WORD = 2;
class AVRMCELFStreamer : public MCELFStreamer {
std::unique_ptr<MCInstrInfo> MCII;
public:
AVRMCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> Emitter)
: MCELFStreamer(Context, std::move(TAB), OS, std::move(Emitter)),
MCII(createAVRMCInstrInfo()) {}
AVRMCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> Emitter,
MCAssembler *Assembler)
: MCELFStreamer(Context, std::move(TAB), OS, std::move(Emitter)),
MCII(createAVRMCInstrInfo()) {}
void EmitValueForModiferKind(
const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc = SMLoc(),
AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None);
};
MCStreamer *createAVRELFStreamer(Triple const &TT, MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> CE);
} // end namespace llvm
#endif // LLVM_LIB_TARGET_AVR_MCTARGETDESC_AVRMCELFSTREAMER_H

View File

@ -1,215 +0,0 @@
//===-- AVRMCExpr.cpp - AVR specific MC expression classes ----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "AVRMCExpr.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCValue.h"
namespace llvm {
namespace {
const struct ModifierEntry {
const char * const Spelling;
AVRMCExpr::VariantKind VariantKind;
} ModifierNames[] = {
{"lo8", AVRMCExpr::VK_AVR_LO8}, {"hi8", AVRMCExpr::VK_AVR_HI8},
{"hh8", AVRMCExpr::VK_AVR_HH8}, // synonym with hlo8
{"hlo8", AVRMCExpr::VK_AVR_HH8}, {"hhi8", AVRMCExpr::VK_AVR_HHI8},
{"pm_lo8", AVRMCExpr::VK_AVR_PM_LO8}, {"pm_hi8", AVRMCExpr::VK_AVR_PM_HI8},
{"pm_hh8", AVRMCExpr::VK_AVR_PM_HH8},
{"lo8_gs", AVRMCExpr::VK_AVR_LO8_GS}, {"hi8_gs", AVRMCExpr::VK_AVR_HI8_GS},
{"gs", AVRMCExpr::VK_AVR_GS},
};
} // end of anonymous namespace
const AVRMCExpr *AVRMCExpr::create(VariantKind Kind, const MCExpr *Expr,
bool Negated, MCContext &Ctx) {
return new (Ctx) AVRMCExpr(Kind, Expr, Negated);
}
void AVRMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
assert(Kind != VK_AVR_None);
if (isNegated())
OS << '-';
OS << getName() << '(';
getSubExpr()->print(OS, MAI);
OS << ')';
}
bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {
MCValue Value;
bool isRelocatable =
getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr);
if (!isRelocatable)
return false;
if (Value.isAbsolute()) {
Result = evaluateAsInt64(Value.getConstant());
return true;
}
return false;
}
bool AVRMCExpr::evaluateAsRelocatableImpl(MCValue &Result,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
MCValue Value;
bool isRelocatable = SubExpr->evaluateAsRelocatable(Value, Layout, Fixup);
if (!isRelocatable)
return false;
if (Value.isAbsolute()) {
Result = MCValue::get(evaluateAsInt64(Value.getConstant()));
} else {
if (!Layout) return false;
MCContext &Context = Layout->getAssembler().getContext();
const MCSymbolRefExpr *Sym = Value.getSymA();
MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
if (Modifier != MCSymbolRefExpr::VK_None)
return false;
Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
Result = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
}
return true;
}
int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {
if (Negated)
Value *= -1;
switch (Kind) {
case AVRMCExpr::VK_AVR_LO8:
Value &= 0xff;
break;
case AVRMCExpr::VK_AVR_HI8:
Value &= 0xff00;
Value >>= 8;
break;
case AVRMCExpr::VK_AVR_HH8:
Value &= 0xff0000;
Value >>= 16;
break;
case AVRMCExpr::VK_AVR_HHI8:
Value &= 0xff000000;
Value >>= 24;
break;
case AVRMCExpr::VK_AVR_PM_LO8:
case AVRMCExpr::VK_AVR_LO8_GS:
Value >>= 1; // Program memory addresses must always be shifted by one.
Value &= 0xff;
break;
case AVRMCExpr::VK_AVR_PM_HI8:
case AVRMCExpr::VK_AVR_HI8_GS:
Value >>= 1; // Program memory addresses must always be shifted by one.
Value &= 0xff00;
Value >>= 8;
break;
case AVRMCExpr::VK_AVR_PM_HH8:
Value >>= 1; // Program memory addresses must always be shifted by one.
Value &= 0xff0000;
Value >>= 16;
break;
case AVRMCExpr::VK_AVR_GS:
Value >>= 1; // Program memory addresses must always be shifted by one.
break;
case AVRMCExpr::VK_AVR_None:
llvm_unreachable("Uninitialized expression.");
}
return static_cast<uint64_t>(Value) & 0xff;
}
AVR::Fixups AVRMCExpr::getFixupKind() const {
AVR::Fixups Kind = AVR::Fixups::LastTargetFixupKind;
switch (getKind()) {
case VK_AVR_LO8:
Kind = isNegated() ? AVR::fixup_lo8_ldi_neg : AVR::fixup_lo8_ldi;
break;
case VK_AVR_HI8:
Kind = isNegated() ? AVR::fixup_hi8_ldi_neg : AVR::fixup_hi8_ldi;
break;
case VK_AVR_HH8:
Kind = isNegated() ? AVR::fixup_hh8_ldi_neg : AVR::fixup_hh8_ldi;
break;
case VK_AVR_HHI8:
Kind = isNegated() ? AVR::fixup_ms8_ldi_neg : AVR::fixup_ms8_ldi;
break;
case VK_AVR_PM_LO8:
Kind = isNegated() ? AVR::fixup_lo8_ldi_pm_neg : AVR::fixup_lo8_ldi_pm;
break;
case VK_AVR_PM_HI8:
Kind = isNegated() ? AVR::fixup_hi8_ldi_pm_neg : AVR::fixup_hi8_ldi_pm;
break;
case VK_AVR_PM_HH8:
Kind = isNegated() ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm;
break;
case VK_AVR_GS:
Kind = AVR::fixup_16_pm;
break;
case VK_AVR_LO8_GS:
Kind = AVR::fixup_lo8_ldi_gs;
break;
case VK_AVR_HI8_GS:
Kind = AVR::fixup_hi8_ldi_gs;
break;
case VK_AVR_None:
llvm_unreachable("Uninitialized expression");
}
return Kind;
}
void AVRMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
Streamer.visitUsedExpr(*getSubExpr());
}
const char *AVRMCExpr::getName() const {
const auto &Modifier = std::find_if(
std::begin(ModifierNames), std::end(ModifierNames),
[this](ModifierEntry const &Mod) { return Mod.VariantKind == Kind; });
if (Modifier != std::end(ModifierNames)) {
return Modifier->Spelling;
}
return nullptr;
}
AVRMCExpr::VariantKind AVRMCExpr::getKindByName(StringRef Name) {
const auto &Modifier = std::find_if(
std::begin(ModifierNames), std::end(ModifierNames),
[&Name](ModifierEntry const &Mod) { return Mod.Spelling == Name; });
if (Modifier != std::end(ModifierNames)) {
return Modifier->VariantKind;
}
return VK_AVR_None;
}
} // end of namespace llvm

View File

@ -1,92 +0,0 @@
//===-- AVRMCExpr.h - AVR specific MC expression classes --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_MCEXPR_H
#define LLVM_AVR_MCEXPR_H
#include "llvm/MC/MCExpr.h"
#include "MCTargetDesc/AVRFixupKinds.h"
namespace llvm {
/// A expression in AVR machine code.
class AVRMCExpr : public MCTargetExpr {
public:
/// Specifies the type of an expression.
enum VariantKind {
VK_AVR_None,
VK_AVR_HI8, ///< Corresponds to `hi8()`.
VK_AVR_LO8, ///< Corresponds to `lo8()`.
VK_AVR_HH8, ///< Corresponds to `hlo8() and hh8()`.
VK_AVR_HHI8, ///< Corresponds to `hhi8()`.
VK_AVR_PM_LO8, ///< Corresponds to `pm_lo8()`.
VK_AVR_PM_HI8, ///< Corresponds to `pm_hi8()`.
VK_AVR_PM_HH8, ///< Corresponds to `pm_hh8()`.
VK_AVR_LO8_GS, ///< Corresponds to `lo8(gs())`.
VK_AVR_HI8_GS, ///< Corresponds to `hi8(gs())`.
VK_AVR_GS, ///< Corresponds to `gs()`.
};
public:
/// Creates an AVR machine code expression.
static const AVRMCExpr *create(VariantKind Kind, const MCExpr *Expr,
bool isNegated, MCContext &Ctx);
/// Gets the type of the expression.
VariantKind getKind() const { return Kind; }
/// Gets the name of the expression.
const char *getName() const;
const MCExpr *getSubExpr() const { return SubExpr; }
/// Gets the fixup which corresponds to the expression.
AVR::Fixups getFixupKind() const;
/// Evaluates the fixup as a constant value.
bool evaluateAsConstant(int64_t &Result) const;
bool isNegated() const { return Negated; }
void setNegated(bool negated = true) { Negated = negated; }
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &streamer) const override;
MCFragment *findAssociatedFragment() const override {
return getSubExpr()->findAssociatedFragment();
}
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
public:
static VariantKind getKindByName(StringRef Name);
private:
int64_t evaluateAsInt64(int64_t Value) const;
const VariantKind Kind;
const MCExpr *SubExpr;
bool Negated;
private:
explicit AVRMCExpr(VariantKind Kind, const MCExpr *Expr, bool Negated)
: Kind(Kind), SubExpr(Expr), Negated(Negated) {}
~AVRMCExpr() {}
};
} // end namespace llvm
#endif // LLVM_AVR_MCEXPR_H

View File

@ -1,127 +0,0 @@
//===-- AVRMCTargetDesc.cpp - AVR Target Descriptions ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides AVR specific target descriptions.
//
//===----------------------------------------------------------------------===//
#include "AVRELFStreamer.h"
#include "AVRMCAsmInfo.h"
#include "AVRMCELFStreamer.h"
#include "AVRMCTargetDesc.h"
#include "AVRTargetStreamer.h"
#include "InstPrinter/AVRInstPrinter.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
#include "AVRGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC
#include "AVRGenSubtargetInfo.inc"
#define GET_REGINFO_MC_DESC
#include "AVRGenRegisterInfo.inc"
using namespace llvm;
MCInstrInfo *llvm::createAVRMCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitAVRMCInstrInfo(X);
return X;
}
static MCRegisterInfo *createAVRMCRegisterInfo(const Triple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitAVRMCRegisterInfo(X, 0);
return X;
}
static MCSubtargetInfo *createAVRMCSubtargetInfo(const Triple &TT,
StringRef CPU, StringRef FS) {
return createAVRMCSubtargetInfoImpl(TT, CPU, FS);
}
static MCInstPrinter *createAVRMCInstPrinter(const Triple &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI) {
if (SyntaxVariant == 0) {
return new AVRInstPrinter(MAI, MII, MRI);
}
return nullptr;
}
static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> &&Emitter,
bool RelaxAll) {
return createELFStreamer(Context, std::move(MAB), OS,
std::move(Emitter), RelaxAll);
}
static MCTargetStreamer *
createAVRObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
return new AVRELFStreamer(S, STI);
}
static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S,
formatted_raw_ostream &OS,
MCInstPrinter *InstPrint,
bool isVerboseAsm) {
return new AVRTargetAsmStreamer(S);
}
extern "C" void LLVMInitializeAVRTargetMC() {
// Register the MC asm info.
RegisterMCAsmInfo<AVRMCAsmInfo> X(getTheAVRTarget());
// Register the MC instruction info.
TargetRegistry::RegisterMCInstrInfo(getTheAVRTarget(), createAVRMCInstrInfo);
// Register the MC register info.
TargetRegistry::RegisterMCRegInfo(getTheAVRTarget(), createAVRMCRegisterInfo);
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(getTheAVRTarget(),
createAVRMCSubtargetInfo);
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(getTheAVRTarget(),
createAVRMCInstPrinter);
// Register the MC Code Emitter
TargetRegistry::RegisterMCCodeEmitter(getTheAVRTarget(), createAVRMCCodeEmitter);
// Register the obj streamer
TargetRegistry::RegisterELFStreamer(getTheAVRTarget(), createMCStreamer);
// Register the obj target streamer.
TargetRegistry::RegisterObjectTargetStreamer(getTheAVRTarget(),
createAVRObjectTargetStreamer);
// Register the asm target streamer.
TargetRegistry::RegisterAsmTargetStreamer(getTheAVRTarget(),
createMCAsmTargetStreamer);
// Register the asm backend (as little endian).
TargetRegistry::RegisterMCAsmBackend(getTheAVRTarget(), createAVRAsmBackend);
}

View File

@ -1,65 +0,0 @@
//===-- AVRMCTargetDesc.h - AVR Target Descriptions -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides AVR specific target descriptions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_MCTARGET_DESC_H
#define LLVM_AVR_MCTARGET_DESC_H
#include "llvm/Support/DataTypes.h"
#include <memory>
namespace llvm {
class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
class MCObjectWriter;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCTargetOptions;
class StringRef;
class Target;
class Triple;
class raw_pwrite_stream;
Target &getTheAVRTarget();
MCInstrInfo *createAVRMCInstrInfo();
/// Creates a machine code emitter for AVR.
MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
MCContext &Ctx);
/// Creates an assembly backend for AVR.
MCAsmBackend *createAVRAsmBackend(const Target &T, const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const llvm::MCTargetOptions &TO);
/// Creates an ELF object writer for AVR.
std::unique_ptr<MCObjectWriter>
createAVRELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI);
} // end namespace llvm
#define GET_REGINFO_ENUM
#include "AVRGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#include "AVRGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM
#include "AVRGenSubtargetInfo.inc"
#endif // LLVM_AVR_MCTARGET_DESC_H

View File

@ -1,44 +0,0 @@
//===-- AVRTargetStreamer.cpp - AVR Target Streamer Methods ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides AVR specific target streamer methods.
//
//===----------------------------------------------------------------------===//
#include "AVRTargetStreamer.h"
#include "llvm/MC/MCContext.h"
namespace llvm {
AVRTargetStreamer::AVRTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
AVRTargetAsmStreamer::AVRTargetAsmStreamer(MCStreamer &S)
: AVRTargetStreamer(S) {}
void AVRTargetStreamer::finish() {
MCStreamer &OS = getStreamer();
MCContext &Context = OS.getContext();
MCSymbol *DoCopyData = Context.getOrCreateSymbol("__do_copy_data");
MCSymbol *DoClearBss = Context.getOrCreateSymbol("__do_clear_bss");
// FIXME: We can disable __do_copy_data if there are no static RAM variables.
OS.emitRawComment(" Declaring this symbol tells the CRT that it should");
OS.emitRawComment("copy all variables from program memory to RAM on startup");
OS.EmitSymbolAttribute(DoCopyData, MCSA_Global);
OS.emitRawComment(" Declaring this symbol tells the CRT that it should");
OS.emitRawComment("clear the zeroed data section on startup");
OS.EmitSymbolAttribute(DoClearBss, MCSA_Global);
}
} // end namespace llvm

View File

@ -1,34 +0,0 @@
//===-- AVRTargetStreamer.h - AVR Target Streamer --------------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_TARGET_STREAMER_H
#define LLVM_AVR_TARGET_STREAMER_H
#include "llvm/MC/MCELFStreamer.h"
namespace llvm {
class MCStreamer;
/// A generic AVR target output stream.
class AVRTargetStreamer : public MCTargetStreamer {
public:
explicit AVRTargetStreamer(MCStreamer &S);
void finish() override;
};
/// A target streamer for textual AVR assembly code.
class AVRTargetAsmStreamer : public AVRTargetStreamer {
public:
explicit AVRTargetAsmStreamer(MCStreamer &S);
};
} // end namespace llvm
#endif // LLVM_AVR_TARGET_STREAMER_H

View File

@ -1,14 +0,0 @@
add_llvm_library(LLVMAVRDesc
AVRAsmBackend.cpp
AVRELFObjectWriter.cpp
AVRELFStreamer.cpp
AVRMCAsmInfo.cpp
AVRMCCodeEmitter.cpp
AVRMCELFStreamer.cpp
AVRMCExpr.cpp
AVRMCTargetDesc.cpp
AVRTargetStreamer.cpp
)
add_dependencies(LLVMAVRDesc AVRCommonTableGen)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/AVR/MCTargetDesc/LLVMBuild.txt --------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = AVRDesc
parent = AVR
required_libraries = MC AVRAsmPrinter AVRInfo Support
add_to_library_groups = AVR