| 1 | //===-- AVRMCCodeEmitter.h - Convert AVR Code to Machine Code -------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file defines the AVRMCCodeEmitter class. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | // |
| 13 | |
| 14 | #ifndef LLVM_AVR_CODE_EMITTER_H |
| 15 | #define LLVM_AVR_CODE_EMITTER_H |
| 16 | |
| 17 | #include "AVRFixupKinds.h" |
| 18 | |
| 19 | #include "llvm/MC/MCCodeEmitter.h" |
| 20 | #include "llvm/Support/DataTypes.h" |
| 21 | |
| 22 | #define GET_INSTRINFO_OPERAND_TYPES_ENUM |
| 23 | #include "AVRGenInstrInfo.inc" |
| 24 | |
| 25 | namespace llvm { |
| 26 | |
| 27 | class MCContext; |
| 28 | class MCExpr; |
| 29 | class MCFixup; |
| 30 | class MCInst; |
| 31 | class MCInstrInfo; |
| 32 | class MCOperand; |
| 33 | class MCSubtargetInfo; |
| 34 | class raw_ostream; |
| 35 | |
| 36 | /// Writes AVR machine code to a stream. |
| 37 | class AVRMCCodeEmitter : public MCCodeEmitter { |
| 38 | public: |
| 39 | AVRMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx) |
| 40 | : MCII(MCII), Ctx(Ctx) {} |
| 41 | |
| 42 | private: |
| 43 | /// Finishes up encoding an LD/ST instruction. |
| 44 | /// The purpose of this function is to set an bit in the instruction |
| 45 | /// which follows no logical pattern. See the implementation for details. |
| 46 | unsigned loadStorePostEncoder(const MCInst &MI, unsigned EncodedValue, |
| 47 | const MCSubtargetInfo &STI) const; |
| 48 | |
| 49 | /// Gets the encoding for a conditional branch target. |
| 50 | template <AVR::Fixups Fixup> |
| 51 | unsigned encodeRelCondBrTarget(const MCInst &MI, unsigned OpNo, |
| 52 | SmallVectorImpl<MCFixup> &Fixups, |
| 53 | const MCSubtargetInfo &STI) const; |
| 54 | |
| 55 | /// Encodes a `register+immediate` operand for `LDD`/`STD`. |
| 56 | unsigned encodeMemri(const MCInst &MI, unsigned OpNo, |
| 57 | SmallVectorImpl<MCFixup> &Fixups, |
| 58 | const MCSubtargetInfo &STI) const; |
| 59 | |
| 60 | /// Takes the complement of a number (~0 - val). |
| 61 | unsigned encodeComplement(const MCInst &MI, unsigned OpNo, |
| 62 | SmallVectorImpl<MCFixup> &Fixups, |
| 63 | const MCSubtargetInfo &STI) const; |
| 64 | |
| 65 | /// Encodes an immediate value with a given fixup. |
| 66 | /// \tparam Offset The offset into the instruction for the fixup. |
| 67 | template <AVR::Fixups Fixup, unsigned Offset> |
| 68 | unsigned encodeImm(const MCInst &MI, unsigned OpNo, |
| 69 | SmallVectorImpl<MCFixup> &Fixups, |
| 70 | const MCSubtargetInfo &STI) const; |
| 71 | |
| 72 | /// Gets the encoding of the target for the `CALL k` instruction. |
| 73 | unsigned encodeCallTarget(const MCInst &MI, unsigned OpNo, |
| 74 | SmallVectorImpl<MCFixup> &Fixups, |
| 75 | const MCSubtargetInfo &STI) const; |
| 76 | |
| 77 | /// TableGen'ed function to get the binary encoding for an instruction. |
| 78 | uint64_t getBinaryCodeForInstr(const MCInst &MI, |
| 79 | SmallVectorImpl<MCFixup> &Fixups, |
| 80 | const MCSubtargetInfo &STI) const; |
| 81 | |
| 82 | unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, |
| 83 | const MCSubtargetInfo &STI) const; |
| 84 | |
| 85 | /// Returns the binary encoding of operand. |
| 86 | /// |
| 87 | /// If the machine operand requires relocation, the relocation is recorded |
| 88 | /// and zero is returned. |
| 89 | unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
| 90 | SmallVectorImpl<MCFixup> &Fixups, |
| 91 | const MCSubtargetInfo &STI) const; |
| 92 | |
| 93 | void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, |
| 94 | SmallVectorImpl<MCFixup> &Fixups, |
| 95 | const MCSubtargetInfo &STI) const override; |
| 96 | |
| 97 | AVRMCCodeEmitter(const AVRMCCodeEmitter &) = delete; |
| 98 | void operator=(const AVRMCCodeEmitter &) = delete; |
| 99 | |
| 100 | const MCInstrInfo &MCII; |
| 101 | MCContext &Ctx; |
| 102 | }; |
| 103 | |
| 104 | } // namespace llvm |
| 105 | |
| 106 | #endif // LLVM_AVR_CODE_EMITTER_H |
| 107 | |