Index: lib/Target/AAP/CMakeLists.txt =================================================================== --- lib/Target/AAP/CMakeLists.txt +++ lib/Target/AAP/CMakeLists.txt @@ -2,10 +2,12 @@ tablegen(LLVM AAPGenRegisterInfo.inc -gen-register-info) tablegen(LLVM AAPGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM AAPGenMCCodeEmitter.inc -gen-emitter) add_public_tablegen_target(AAPCommonTableGen) add_llvm_target(AAPCodeGen AAPTargetMachine.cpp ) +add_subdirectory(MCTargetDesc) add_subdirectory(TargetInfo) Index: lib/Target/AAP/LLVMBuild.txt =================================================================== --- lib/Target/AAP/LLVMBuild.txt +++ lib/Target/AAP/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = TargetInfo +subdirectories = MCTargetDesc TargetInfo [component_0] type = TargetGroup Index: lib/Target/AAP/MCTargetDesc/AAPAsmBackend.cpp =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPAsmBackend.cpp @@ -0,0 +1,179 @@ +//===-- AAPAsmBackend.cpp - AAP Assembler Backend -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AAPMCTargetDesc.h" +#include "MCTargetDesc/AAPFixupKinds.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCObjectWriter.h" + +using namespace llvm; + +namespace { + +class AAPAsmBackend : public MCAsmBackend { +public: + AAPAsmBackend(Target const &T) {} + + unsigned getNumFixupKinds() const override { return 14; } + + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { + const static MCFixupKindInfo Infos[AAP::NumTargetFixupKinds] = { + // We tell LLVM that branches are not PC relative to prevent it from + // resolving them, these are more complex fields which we instead want + // populate in the linker. + + // This table *must* be in the order that the fixup_* kinds are defined + // in + // AAPFixupKinds.h. + // + // Name offset size flags + {"fixup_AAP_NONE", 0, 16, 0}, + {"fixup_AAP_BR16", 0, 9, 0}, + {"fixup_AAP_BR32", 0, 9, 0}, + {"fixup_AAP_BRCC16", 6, 3, 0}, + {"fixup_AAP_BRCC32", 6, 3, 0}, + {"fixup_AAP_BAL16", 0, 3, 0}, + {"fixup_AAP_BAL32", 0, 3, 0}, + {"fixup_AAP_ABS6", 0, 3, 0}, + {"fixup_AAP_ABS9", 0, 3, 0}, + {"fixup_AAP_ABS10", 0, 3, 0}, + {"fixup_AAP_ABS12", 0, 6, 0}, + {"fixup_AAP_ABS16", 0, 6, 0}, + {"fixup_AAP_SHIFT6", 0, 3, 0}, + {"fixup_AAP_OFF10", 0, 3, 0} + }; + + if (Kind < FirstTargetFixupKind) + return MCAsmBackend::getFixupKindInfo(Kind); + + assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && + "Invalid kind!"); + return Infos[Kind - FirstTargetFixupKind]; + } + +//===-------------------------- Fixup processing --------------------------===// + + void applyFixup(MCFixup const &Fixup, char *Data, unsigned DataSize, + uint64_t Value, bool IsPCRel) const override { + // No target specific fixups are applied in the backend as they are all + // handled as relocations in the linker. + // Generic relocations are handled, as they may be literal values which + // need to be resolved before they reach the linker. + unsigned Size = 0; + switch ((unsigned)Fixup.getKind()) { + case FK_Data_1: + Size = 1; + break; + case FK_Data_2: + Size = 2; + break; + case FK_Data_4: + Size = 4; + break; + case FK_Data_8: + Size = 8; + break; + default: + return; + } + for (unsigned i = 0; i < Size; ++i) { + Data[i + Fixup.getOffset()] = static_cast(Value >> (i * 8)); + } + return; + } + + void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFixup &Fixup, const MCFragment *DF, + const MCValue &Target, uint64_t &Value, + bool &isResolved) override { + // No AAP specific fixups are processed in the backend. + switch ((unsigned)Fixup.getKind()) { + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + case FK_Data_8: + isResolved = true; + default: + return; + } + isResolved = false; + } + +//===------------------------ Relaxation interface ------------------------===// + + bool mayNeedRelaxation(MCInst const &Inst) const override { + // We already generate the longest instruction necessary, so there is + // nothing to relax. + return false; + } + + bool fixupNeedsRelaxation(MCFixup const &Fixup, uint64_t Value, + MCRelaxableFragment const *DF, + MCAsmLayout const &Layout) const override { + // We already generate the longest instruction necessary so there is + // no need to relax, and at the moment we should never see fixups for + // short instructions. + switch ((unsigned)Fixup.getKind()) { + case AAP::fixup_AAP_BR16: + case AAP::fixup_AAP_BRCC16: + case AAP::fixup_AAP_BAL16: + llvm_unreachable("Cannot relax short instruction fixups!"); + default: + return false; + } + } + + void relaxInstruction(MCInst const &Inst, const MCSubtargetInfo &STI, + MCInst &Res) const override { + // The only instructions which should require relaxation are short + // instructions with fixups, and at the moment these instructions should + // not be selected or parsed + llvm_unreachable("Unexpected short instruction with fixup"); + } + + bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override { + if ((Count % 2) != 0) { + return false; + } + + // 0x0001 corresponds to nop $r0, 1 + for (uint64_t i = 0; i < Count; i += 2) { + OW->write16(0x0001); + } + return true; + } +}; +} // end anonymous namespace + +namespace { +class ELFAAPAsmBackend : public AAPAsmBackend { + uint8_t OSABI; + +public: + ELFAAPAsmBackend(Target const &T, uint8_t OSABI) + : AAPAsmBackend(T), OSABI(OSABI) {} + + MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { + StringRef CPU("Default"); + return createAAPELFObjectWriter(OS, OSABI, CPU); + } +}; +} // end anonymous namespace + +namespace llvm { +MCAsmBackend *createAAPAsmBackend(const Target &T, const MCRegisterInfo &MRI, + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options) { + uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); + return new ELFAAPAsmBackend(T, OSABI); +} +} Index: lib/Target/AAP/MCTargetDesc/AAPELFObjectWriter.cpp =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPELFObjectWriter.cpp @@ -0,0 +1,83 @@ +//===-- AAPELFObjectWriter.cpp - AAP Target Descriptions ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AAP.h" +#include "AAPMCTargetDesc.h" +#include "MCTargetDesc/AAPFixupKinds.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "aap-elfwriter" + +using namespace llvm; + +namespace { + +class AAPELFObjectWriter : public MCELFObjectTargetWriter { +private: + StringRef CPU; + +public: + AAPELFObjectWriter(uint8_t OSABI, StringRef C); + + unsigned getRelocType(MCContext &Ctx, MCValue const &Target, + MCFixup const &Fixup, bool IsPCRel) const override; +}; +} + +AAPELFObjectWriter::AAPELFObjectWriter(uint8_t OSABI, StringRef C) + : MCELFObjectTargetWriter(/*Is64bit*/ false, OSABI, ELF::EM_AAP, + /*HasRelocationAddend*/ true), + CPU(C) {} + +unsigned AAPELFObjectWriter::getRelocType(MCContext & /*Ctx*/, + MCValue const & /*Target*/, + MCFixup const &Fixup, + bool IsPCRel) const { + llvm::MCFixupKind Kind = Fixup.getKind(); + + switch ((unsigned)Kind) { + case AAP::fixup_AAP_NONE: return ELF::R_AAP_NONE; + case AAP::fixup_AAP_BR32: return ELF::R_AAP_BR32; + case AAP::fixup_AAP_BRCC32: return ELF::R_AAP_BRCC32; + case AAP::fixup_AAP_BAL32: return ELF::R_AAP_BAL32; + + case AAP::fixup_AAP_ABS6: return ELF::R_AAP_ABS6; + case AAP::fixup_AAP_ABS9: return ELF::R_AAP_ABS9; + case AAP::fixup_AAP_ABS10: return ELF::R_AAP_ABS10; + case AAP::fixup_AAP_ABS12: return ELF::R_AAP_ABS12; + case AAP::fixup_AAP_ABS16: return ELF::R_AAP_ABS16; + + case AAP::fixup_AAP_SHIFT6: return ELF::R_AAP_SHIFT6; + case AAP::fixup_AAP_OFF10: return ELF::R_AAP_OFF10; + + case FK_Data_1: return ELF::R_AAP_8; + case FK_Data_2: return ELF::R_AAP_16; + case FK_Data_4: return ELF::R_AAP_32; + case FK_Data_8: return ELF::R_AAP_64; + + // Instrs with these fixups should never be generated or parsed, so for now + // we should not be emitting relocations for them. + case AAP::fixup_AAP_BR16: + case AAP::fixup_AAP_BRCC16: + case AAP::fixup_AAP_BAL16: + llvm_unreachable("Cannot emit relocations for short instruction fixups!"); + default: + llvm_unreachable("Unimplemented fixup kind!"); + } + return ELF::R_AAP_NONE; +} + +MCObjectWriter *llvm::createAAPELFObjectWriter(raw_pwrite_stream &OS, + uint8_t OSABI, StringRef CPU) { + MCELFObjectTargetWriter *MOTW = new AAPELFObjectWriter(OSABI, CPU); + return createELFObjectWriter(MOTW, OS, /*IsLittleEndian*/ true); +} Index: lib/Target/AAP/MCTargetDesc/AAPFixupKinds.h =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPFixupKinds.h @@ -0,0 +1,58 @@ +//===-- AAPFixupKinds.h - AAP 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_AAP_AAPFIXUPKINDS_H +#define LLVM_AAP_AAPFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +namespace llvm { +namespace AAP { +// 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. +// +// This table *must* be in the save order of +// MCFixupKindInfo Infos[AAP::NumTargetFixupKinds] +// in AAPAsmBackend.cpp. +// +enum Fixups { + // Results in R_AAP_NONE + fixup_AAP_NONE = FirstTargetFixupKind, + + // Fixup for resolving branches to other basic blocks + fixup_AAP_BR16, + fixup_AAP_BR32, + + // Fixup for resolving conditional branches to other basic blocks + fixup_AAP_BRCC16, + fixup_AAP_BRCC32, + + // Branch and link fixups + fixup_AAP_BAL16, + fixup_AAP_BAL32, + + // Fixup for absolute values + fixup_AAP_ABS6, + fixup_AAP_ABS9, + fixup_AAP_ABS10, + fixup_AAP_ABS12, + fixup_AAP_ABS16, + + // Shift and offset fixups + fixup_AAP_SHIFT6, + fixup_AAP_OFF10, + + // Marker + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +}; +} // end namespace AAP +} // end namespace llvm + +#endif Index: lib/Target/AAP/MCTargetDesc/AAPMCAsmInfo.h =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPMCAsmInfo.h @@ -0,0 +1,32 @@ +//===-- AAPMCAsmInfo.h - AAP 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 AAPMCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AAP_MCTARGETDESC_AAPMCASMINFO_H +#define LLVM_LIB_TARGET_AAP_MCTARGETDESC_AAPMCASMINFO_H + +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCAsmInfoELF.h" + +namespace llvm { +class StringRef; + +class AAPMCAsmInfo : public MCAsmInfoELF { + void anchor() override; + +public: + explicit AAPMCAsmInfo(const Triple &TT); +}; + +} // namespace llvm + +#endif Index: lib/Target/AAP/MCTargetDesc/AAPMCAsmInfo.cpp =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPMCAsmInfo.cpp @@ -0,0 +1,27 @@ +//===-- AAPMCAsmInfo.cpp - AAP 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 AAPMCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "AAPMCAsmInfo.h" +#include "llvm/ADT/Triple.h" + +using namespace llvm; + +void AAPMCAsmInfo::anchor() {} + +AAPMCAsmInfo::AAPMCAsmInfo(const llvm::Triple &TT) { + CalleeSaveStackSlotSize = 2; + PointerSize = 4; + CommentString = ";"; + SupportsDebugInformation = true; + UsesELFSectionDirectiveForBSS = true; +} Index: lib/Target/AAP/MCTargetDesc/AAPMCCodeEmitter.h =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPMCCodeEmitter.h @@ -0,0 +1,97 @@ +//===-- AAPMCCodeEmitter.h - AAP Code Emitter -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// Definition for classes that emit AAP machine code from MCInsts +/// +//===----------------------------------------------------------------------===// + +#ifndef AAPMCCODEEMITTER_H +#define AAPMCCODEEMITTER_H + +#include "llvm/MC/MCCodeEmitter.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/raw_ostream.h" + +namespace llvm { + +class AAPMCCodeEmitter : public MCCodeEmitter { + MCContext &MCtx; + MCInstrInfo const &MCII; + +public: + AAPMCCodeEmitter(MCInstrInfo const &aMII, MCContext &aMCT); + + MCSubtargetInfo const &getSubtargetInfo() const; + + void encodeInstruction(MCInst const &MI, raw_ostream &OS, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const override; + + unsigned encodePCRelImmOperand(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned encodeMemSrcOperand(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + + unsigned encodeImmN(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI, MCFixupKind FixupKind) const; + unsigned encodeImm3(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + unsigned encodeImm6(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + unsigned encodeImm9(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + unsigned encodeImm10(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + unsigned encodeImm12(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + + unsigned encodeField16(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + + unsigned encodeShiftConst3(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + unsigned encodeShiftImm6(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + + // TableGen'erated function for getting the + // binary encoding for an instruction. + uint64_t getBinaryCodeForInstr(MCInst const &MI, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + + /// Return binary encoding of operand. + unsigned getMachineOpValue(MCInst const &MI, MCOperand const &MO, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const; + +private: + AAPMCCodeEmitter(AAPMCCodeEmitter const &) = delete; + void operator=(AAPMCCodeEmitter const &) = delete; +}; // class AAPMCCodeEmitter + +} // namespace llvm + +#endif /* AAPMCCODEEMITTER_H */ Index: lib/Target/AAP/MCTargetDesc/AAPMCCodeEmitter.cpp =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPMCCodeEmitter.cpp @@ -0,0 +1,281 @@ +//===-- AAPMCCodeEmitter.cpp - AAP Target Descriptions --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/AAPMCCodeEmitter.h" +#include "AAP.h" +#include "MCTargetDesc/AAPFixupKinds.h" +#include "MCTargetDesc/AAPMCTargetDesc.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/MC/MCCodeEmitter.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/Debug.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "aap-codemitter" + +using namespace llvm; +using namespace AAP; + +STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); + +namespace { +void emitLittleEndian(uint64_t Encoding, raw_ostream &OS, unsigned sz) { + while (sz > 0) { + OS << static_cast(Encoding & 0xff); + Encoding = Encoding >> 8; + sz--; + } +} +} + +AAPMCCodeEmitter::AAPMCCodeEmitter(MCInstrInfo const &MII, MCContext &Context) + : MCtx(Context), MCII(MII) {} + +void AAPMCCodeEmitter::encodeInstruction(MCInst const &MI, raw_ostream &OS, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const { + const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); + uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); + emitLittleEndian(Binary, OS, Desc.getSize()); + ++MCNumEmitted; +} + +unsigned AAPMCCodeEmitter::getMachineOpValue(MCInst const &MI, + MCOperand const &MO, + SmallVectorImpl &Fixups, + MCSubtargetInfo const &STI) const { + if (MO.isReg()) + return MCtx.getRegisterInfo()->getEncodingValue(MO.getReg()); + if (MO.isImm()) + return static_cast(MO.getImm()); + + // MO must be an expression + assert(MO.isExpr()); + + const MCExpr *Expr = MO.getExpr(); + MCExpr::ExprKind Kind = Expr->getKind(); + + if (Kind == MCExpr::Binary) { + Expr = static_cast(Expr)->getLHS(); + Kind = Expr->getKind(); + } + + assert(Kind == MCExpr::SymbolRef); + + AAP::Fixups FixupKind = AAP::Fixups(0); + const unsigned Opcode = MI.getOpcode(); + if (Opcode == AAP::BAL) { + FixupKind = AAP::fixup_AAP_BAL32; + } else if (Opcode == AAP::BAL_short) { + FixupKind = AAP::fixup_AAP_BAL16; + } else { + llvm_unreachable("Unknown fixup kind!"); + } + + // Push fixup, encoding 0 as the current operand + Fixups.push_back( + MCFixup::create(0, MO.getExpr(), MCFixupKind(FixupKind), MI.getLoc())); + return 0; +} + +MCCodeEmitter *llvm::createAAPMCCodeEmitter(MCInstrInfo const &MII, + MCRegisterInfo const &MRI, + MCContext &Context) { + return new AAPMCCodeEmitter(MII, Context); +} + +// TODO: Better way than using LUTs? +static const unsigned BRCCOpcodes[] = { + AAP::BEQ_, AAP::BNE_, AAP::BLTS_, + AAP::BLES_, AAP::BLTU_, AAP::BLEU_, + + AAP::BEQ_short, AAP::BNE_short, AAP::BLTS_short, + AAP::BLES_short, AAP::BLTU_short, AAP::BLEU_short}; + +static bool findOpcode(unsigned Op, ArrayRef Opcodes) { + for (auto It = Opcodes.begin(); It != Opcodes.end(); It++) { + if (Op == *It) { + return true; + } + } + return false; +} + +unsigned +AAPMCCodeEmitter::encodePCRelImmOperand(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Op); + if (MO.isReg() || MO.isImm()) { + return getMachineOpValue(MI, MO, Fixups, STI); + } + + const unsigned Opcode = MI.getOpcode(); + AAP::Fixups FixupKind; + switch (Opcode) { + case AAP::BRA: + FixupKind = AAP::fixup_AAP_BR32; + break; + case AAP::BRA_short: + FixupKind = AAP::fixup_AAP_BR16; + break; + case AAP::BAL: + FixupKind = AAP::fixup_AAP_BAL32; + break; + case AAP::BAL_short: + FixupKind = AAP::fixup_AAP_BAL16; + break; + default: + FixupKind = AAP::fixup_AAP_NONE; + if (findOpcode(Opcode, BRCCOpcodes)) { + const MCInstrDesc &Desc = MCII.get(Opcode); + if (Desc.getSize() == 4) { + FixupKind = AAP::fixup_AAP_BRCC32; + } else { + FixupKind = AAP::fixup_AAP_BRCC16; + } + } else { + llvm_unreachable("Cannot encode fixup for non-branch pc-relative imm"); + } + } + Fixups.push_back(MCFixup::create(0, MO.getExpr(), (MCFixupKind)FixupKind)); + return 0; +} + +unsigned +AAPMCCodeEmitter::encodeMemSrcOperand(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + unsigned encoding; + + // Map register number to its encoding, encode in upper 16 bits + const MCOperand RegOp = MI.getOperand(Op); + assert(RegOp.isReg() && "First operand is not a register!"); + + unsigned Reg = MCtx.getRegisterInfo()->getEncodingValue(RegOp.getReg()); + encoding = (Reg & 0xffff) << 16; + + // Immediates map directly to their encoding, map into lower 16 bits + MCOperand ImmOp = MI.getOperand(Op + 1); + if (ImmOp.isImm()) { + encoding |= static_cast(ImmOp.getImm()) & 0xffff; + return encoding; + } + + // Not an immediate, check for an expression and store as fixup to be + // resolved later + assert(ImmOp.isExpr() && "Second memsrc op not an immediate or expression!"); + + const unsigned Opcode = MI.getOpcode(); + const MCInstrDesc &Desc = MCII.get(Opcode); + assert(Desc.getSize() == 4 && + "Cannot encode an expression in a short memory+offset operand"); + + AAP::Fixups FixupKind = AAP::fixup_AAP_OFF10; + Fixups.push_back(MCFixup::create(0, ImmOp.getExpr(), MCFixupKind(FixupKind))); + return encoding; +} + +// Try to encode an immediate directly. If that is not possible then emit a +// provided fixup kind. +// +// The FixupKind is assumed to be a AAP specific fixup, if it is not then it +// signifies that a fixup cannot be emitted for the provided immediate. +unsigned AAPMCCodeEmitter::encodeImmN(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI, + MCFixupKind FixupKind) const { + const MCOperand MO = MI.getOperand(Op); + if (MO.isImm()) { + return static_cast(MO.getImm()); + } + assert(MO.isExpr()); + assert(MCII.get(MI.getOpcode()).getSize() == 4 && + "Cannot encode fixups for short instruction immediates"); + + if (FixupKind >= FirstTargetFixupKind) { + Fixups.push_back(MCFixup::create(0, MO.getExpr(), FixupKind)); + } else { + llvm_unreachable("Cannot encode a fixup for this immediate operand"); + } + return 0; +} + +unsigned AAPMCCodeEmitter::encodeImm3(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + return encodeImmN(MI, Op, Fixups, STI, static_cast(0)); +} + +unsigned AAPMCCodeEmitter::encodeImm6(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + return encodeImmN(MI, Op, Fixups, STI, MCFixupKind(AAP::fixup_AAP_ABS6)); +} + +unsigned AAPMCCodeEmitter::encodeImm9(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + return encodeImmN(MI, Op, Fixups, STI, MCFixupKind(AAP::fixup_AAP_ABS9)); +} + +unsigned AAPMCCodeEmitter::encodeImm10(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + return encodeImmN(MI, Op, Fixups, STI, MCFixupKind(AAP::fixup_AAP_ABS10)); +} + +unsigned AAPMCCodeEmitter::encodeImm12(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + return encodeImmN(MI, Op, Fixups, STI, MCFixupKind(AAP::fixup_AAP_ABS12)); +} + +unsigned AAPMCCodeEmitter::encodeField16(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + return encodeImmN(MI, Op, Fixups, STI, MCFixupKind(AAP::fixup_AAP_ABS16)); +} + +unsigned AAPMCCodeEmitter::encodeShiftConst3(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand MO = MI.getOperand(Op); + if (MO.isImm()) { + // Subtract one to get the actual encoding of the shift value + unsigned value = MO.getImm(); + return static_cast(value - 1); + } else { + llvm_unreachable("Cannot encode an expression in a short shift operand"); + } + return 0; +} + +unsigned AAPMCCodeEmitter::encodeShiftImm6(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand MO = MI.getOperand(Op); + if (MO.isImm()) { + // Subtract one to get the actual encoding of the shift value + unsigned value = MO.getImm(); + return static_cast(value - 1); + } + assert(MO.isExpr()); + AAP::Fixups FixupKind = AAP::fixup_AAP_SHIFT6; + Fixups.push_back(MCFixup::create(0, MO.getExpr(), MCFixupKind(FixupKind))); + return 0; +} + +#include "AAPGenMCCodeEmitter.inc" Index: lib/Target/AAP/MCTargetDesc/AAPMCTargetDesc.h =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPMCTargetDesc.h @@ -0,0 +1,56 @@ +//===-- AAPMCTargetDesc.h - AAP 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 AAP specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AAP_MCTARGETDESC_AAPMCTARGETDESC_H +#define LLVM_LIB_TARGET_AAP_MCTARGETDESC_AAPMCTARGETDESC_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; +class MCObjectWriter; +class MCRegisterInfo; +class MCTargetOptions; +class StringRef; +class Target; +class Triple; +class raw_pwrite_stream; + +extern Target TheAAPTarget; + +MCCodeEmitter *createAAPMCCodeEmitter(MCInstrInfo const &MCII, + MCRegisterInfo const &MRI, + MCContext &Context); + +MCAsmBackend *createAAPAsmBackend(const Target &T, const MCRegisterInfo &MRI, + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options); + +MCObjectWriter *createAAPELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, + StringRef CPU); + +} // End llvm namespace + +// Defines symbolic names for AAP registers. +// This defines a mapping from register name to register number. +#define GET_REGINFO_ENUM +#include "AAPGenRegisterInfo.inc" + +// Defines symbolic names for the AAP instructions. +#define GET_INSTRINFO_ENUM +#include "AAPGenInstrInfo.inc" + +#endif Index: lib/Target/AAP/MCTargetDesc/AAPMCTargetDesc.cpp =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/AAPMCTargetDesc.cpp @@ -0,0 +1,65 @@ +//===-- AAPMCTargetDesc.cpp - AAP 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 AAP specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#include "AAPMCTargetDesc.h" +#include "AAPMCAsmInfo.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +#define GET_INSTRINFO_MC_DESC +#include "AAPGenInstrInfo.inc" + +#define GET_REGINFO_MC_DESC +#include "AAPGenRegisterInfo.inc" + +static MCInstrInfo *createAAPMCInstrInfo() { + MCInstrInfo *X = new MCInstrInfo(); + InitAAPMCInstrInfo(X); + return X; +} + +static MCRegisterInfo *createAAPMCRegisterInfo(const Triple &TT) { + MCRegisterInfo *X = new MCRegisterInfo(); + InitAAPMCRegisterInfo(X, AAP::R0); + return X; +} + +static void adjustCodeGenOpts(const Triple &TT, Reloc::Model RM, + CodeModel::Model &CM) { + return; +} + +extern "C" void LLVMInitializeAAPTargetMC() { + // Register the MC asm info. + RegisterMCAsmInfo X(TheAAPTarget); + + // Register the MC codegen info. + TargetRegistry::registerMCAdjustCodeGenOpts(TheAAPTarget, adjustCodeGenOpts); + + // Register the MC instruction info. + TargetRegistry::RegisterMCInstrInfo(TheAAPTarget, createAAPMCInstrInfo); + + // Register the MC register info. + TargetRegistry::RegisterMCRegInfo(TheAAPTarget, createAAPMCRegisterInfo); + + // Register the MC Code Emitter + TargetRegistry::RegisterMCCodeEmitter(TheAAPTarget, createAAPMCCodeEmitter); + + // Register the asm backend + TargetRegistry::RegisterMCAsmBackend(TheAAPTarget, createAAPAsmBackend); +} Index: lib/Target/AAP/MCTargetDesc/CMakeLists.txt =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/CMakeLists.txt @@ -0,0 +1,7 @@ +add_llvm_library(LLVMAAPDesc + AAPAsmBackend.cpp + AAPELFObjectWriter.cpp + AAPMCAsmInfo.cpp + AAPMCCodeEmitter.cpp + AAPMCTargetDesc.cpp + ) Index: lib/Target/AAP/MCTargetDesc/LLVMBuild.txt =================================================================== --- /dev/null +++ lib/Target/AAP/MCTargetDesc/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/Target/AAP/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 = AAPDesc +parent = AAP +required_libraries = MC Support AAPInfo +add_to_library_groups = AAP Index: lib/Target/AAP/TargetInfo/AAPTargetInfo.cpp =================================================================== --- lib/Target/AAP/TargetInfo/AAPTargetInfo.cpp +++ lib/Target/AAP/TargetInfo/AAPTargetInfo.cpp @@ -19,8 +19,3 @@ extern "C" void LLVMInitializeAAPTargetInfo() { RegisterTarget X(TheAAPTarget, "aap", "AAP [experimental]"); } - -// Placeholder. This will be removed when the MC support has been -// introduced -extern "C" void LLVMInitializeAAPTargetMC() { -}