diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/Target/AVR/MCTargetDesc | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'llvm/lib/Target/AVR/MCTargetDesc')
10 files changed, 94 insertions, 69 deletions
diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp index e92b16c8ee9d6..ac72abe0d9f68 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp @@ -34,8 +34,9 @@ namespace adjust { using namespace llvm; -void signed_width(unsigned Width, uint64_t Value, std::string Description, - const MCFixup &Fixup, MCContext *Ctx = nullptr) { +static 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; @@ -53,8 +54,9 @@ void signed_width(unsigned Width, uint64_t Value, std::string Description, } } -void unsigned_width(unsigned Width, uint64_t Value, std::string Description, - const MCFixup &Fixup, MCContext *Ctx = nullptr) { +static 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; @@ -72,8 +74,8 @@ void unsigned_width(unsigned Width, uint64_t Value, std::string Description, } /// Adjusts the value of a branch target before fixup application. -void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static 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); @@ -83,14 +85,12 @@ void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &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) { +static 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); } @@ -101,8 +101,8 @@ void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value, /// 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) { +static 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 @@ -117,8 +117,8 @@ void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value, /// 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) { +static 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 @@ -131,21 +131,33 @@ void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value, /// 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) { +static 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 STD/LDD family of +/// instructions. +/// +/// Resolves to: +/// 10q0 qq10 0000 1qqq +static void fixup_6(const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { + unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx); + + Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07); +} + /// 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) { +static 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); @@ -155,8 +167,8 @@ void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value, /// /// Resolves to: /// 0000 0000 AAAA A000 -void fixup_port5(const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { unsigned_width(5, Value, std::string("port number"), Fixup, Ctx); Value &= 0x1f; @@ -168,8 +180,8 @@ void fixup_port5(const MCFixup &Fixup, uint64_t &Value, /// /// Resolves to: /// 1011 0AAd dddd AAAA -void fixup_port6(const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static 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); @@ -177,9 +189,7 @@ void fixup_port6(const MCFixup &Fixup, uint64_t &Value, /// Adjusts a program memory address. /// This is a simple right-shift. -void pm(uint64_t &Value) { - Value >>= 1; -} +static void pm(uint64_t &Value) { Value >>= 1; } /// Fixups relating to the LDI instruction. namespace ldi { @@ -189,36 +199,36 @@ namespace ldi { /// 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) { +static 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; } +static void neg(uint64_t &Value) { Value *= -1; } -void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, - MCContext *Ctx = nullptr) { +static 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) { +static 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) { +static 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) { +static void ms8(unsigned Size, const MCFixup &Fixup, uint64_t &Value, + MCContext *Ctx = nullptr) { Value = (Value & 0xff000000) >> 24; ldi::fixup(Size, Fixup, Value, Ctx); } @@ -237,17 +247,6 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, 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"); @@ -326,6 +325,9 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, Value &= 0xffff; break; + case AVR::fixup_6: + adjust::fixup_6(Fixup, Value, Ctx); + break; case AVR::fixup_6_adiw: adjust::fixup_6_adiw(Fixup, Value, Ctx); break; diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h index 1e713db38145d..9e150f120dd4d 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h @@ -22,9 +22,6 @@ namespace llvm { class MCAssembler; -class MCObjectWriter; -class Target; - struct MCFixupKindInfo; /// Utilities for manipulating generated AVR machine code. @@ -62,9 +59,6 @@ public: return false; } - void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, - MCInst &Res) const override {} - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h index b3504b89e4d33..a0dd1dc8ac3ec 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h @@ -137,7 +137,7 @@ namespace fixups { /// 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. +/// \param [in,out] val The target to adjust. template <typename T> inline void adjustBranchTarget(T &val) { val >>= 1; } } // end of namespace fixups diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp index 832112406155a..42fac5e2e000e 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.cpp @@ -78,7 +78,7 @@ void AVRInstPrinter::printInst(const MCInst *MI, uint64_t Address, printOperand(MI, 2, O); break; default: - if (!printAliasInstr(MI, O)) + if (!printAliasInstr(MI, Address, O)) printInstruction(MI, Address, O); printAnnotation(O, Annot); @@ -100,8 +100,25 @@ const char *AVRInstPrinter::getPrettyRegisterName(unsigned RegNum, void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { - const MCOperand &Op = MI->getOperand(OpNo); const MCOperandInfo &MOI = this->MII.get(MI->getOpcode()).OpInfo[OpNo]; + if (MOI.RegClass == AVR::ZREGRegClassID) { + // Special case for the Z register, which sometimes doesn't have an operand + // in the MCInst. + O << "Z"; + return; + } + + if (OpNo >= MI->size()) { + // Not all operands are correctly disassembled at the moment. This means + // that some machine instructions won't have all the necessary operands + // set. + // To avoid asserting, print <unknown> instead until the necessary support + // has been implemented. + O << "<unknown>"; + return; + } + + const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) { bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) || @@ -114,7 +131,7 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, O << getPrettyRegisterName(Op.getReg(), MRI); } } else if (Op.isImm()) { - O << Op.getImm(); + O << formatImm(Op.getImm()); } else { assert(Op.isExpr() && "Unknown operand kind in printOperand"); O << *Op.getExpr(); @@ -125,6 +142,16 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, /// being encoded as a pc-relative value. void AVRInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O) { + if (OpNo >= MI->size()) { + // Not all operands are correctly disassembled at the moment. This means + // that some machine instructions won't have all the necessary operands + // set. + // To avoid asserting, print <unknown> instead until the necessary support + // has been implemented. + O << "<unknown>"; + return; + } + const MCOperand &Op = MI->getOperand(OpNo); if (Op.isImm()) { diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h index 247e9fc839897..910fd3455dee3 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h @@ -38,13 +38,18 @@ private: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printPCRelImm(const MCInst *MI, uint64_t /*Address*/, unsigned OpNo, + raw_ostream &O) { + printPCRelImm(MI, OpNo, O); + } void printMemri(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by TableGen. void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); - bool printAliasInstr(const MCInst *MI, raw_ostream &O); - void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, - unsigned PrintMethodIdx, raw_ostream &O); + bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &O); + void printCustomAliasOperand(const MCInst *MI, uint64_t Address, + unsigned OpIdx, unsigned PrintMethodIdx, + raw_ostream &O); }; } // end namespace llvm diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp index c25a2b2320138..b11ee42bfcd6e 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp @@ -21,8 +21,8 @@ AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) { CalleeSaveStackSlotSize = 2; CommentString = ";"; PrivateGlobalPrefix = ".L"; + PrivateLabelPrefix = ".L"; UsesELFSectionDirectiveForBSS = true; - UseIntegratedAssembler = true; SupportsDebugInformation = true; } diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp index d9169f90a765b..77b49931843b4 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp @@ -20,7 +20,7 @@ using namespace llvm; -void AVRMCELFStreamer::EmitValueForModiferKind( +void AVRMCELFStreamer::emitValueForModiferKind( const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc, AVRMCExpr::VariantKind ModifierKind) { MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_AVR_NONE; @@ -36,7 +36,7 @@ void AVRMCELFStreamer::EmitValueForModiferKind( Kind = MCSymbolRefExpr::VK_AVR_HI8; else if (ModifierKind == AVRMCExpr::VK_AVR_HH8) Kind = MCSymbolRefExpr::VK_AVR_HLO8; - MCELFStreamer::EmitValue(MCSymbolRefExpr::create(Sym, Kind, getContext()), + MCELFStreamer::emitValue(MCSymbolRefExpr::create(Sym, Kind, getContext()), SizeInBytes, Loc); } diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h index 37a610bc4248f..1d05b8d56d930 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h @@ -41,7 +41,7 @@ public: std::move(Emitter)), MCII(createAVRMCInstrInfo()) {} - void EmitValueForModiferKind( + void emitValueForModiferKind( const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc = SMLoc(), AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None); }; diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h index 470db01ff4689..ef116793d326e 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h @@ -27,10 +27,7 @@ class MCObjectTargetWriter; class MCRegisterInfo; class MCSubtargetInfo; class MCTargetOptions; -class StringRef; class Target; -class Triple; -class raw_pwrite_stream; MCInstrInfo *createAVRMCInstrInfo(); diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp index 3487a2bbb8640..eccd343d79abc 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp @@ -32,11 +32,11 @@ void AVRTargetStreamer::finish() { 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.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); + OS.emitSymbolAttribute(DoClearBss, MCSA_Global); } } // end namespace llvm |