30 #define DEBUG_TYPE "mccodeemitter"
32 #define GET_INSTRMAP_INFO
33 #include "AVRGenInstrInfo.inc"
34 #undef GET_INSTRMAP_INFO
67 AVRMCCodeEmitter::loadStorePostEncoder(
const MCInst &
MI,
unsigned EncodedValue,
68 const MCSubtargetInfo &STI)
const {
70 assert(MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
71 "the load/store operands must be registers");
73 unsigned Opcode = MI.getOpcode();
76 bool IsRegX = MI.getOperand(0).getReg() == AVR::R27R26 ||
77 MI.getOperand(1).getReg() == AVR::R27R26;
79 bool IsPredec = Opcode == AVR::LDRdPtrPd || Opcode == AVR::STPtrPdRr;
80 bool IsPostinc = Opcode == AVR::LDRdPtrPi || Opcode == AVR::STPtrPiRr;
83 if (IsRegX || IsPredec || IsPostinc) {
84 EncodedValue |= (1 << 12);
90 template <AVR::Fixups Fixup>
92 AVRMCCodeEmitter::encodeRelCondBrTarget(
const MCInst &MI,
unsigned OpNo,
93 SmallVectorImpl<MCFixup> &
Fixups,
94 const MCSubtargetInfo &STI)
const {
95 const MCOperand &MO = MI.getOperand(OpNo);
107 auto target = MO.getImm();
112 unsigned AVRMCCodeEmitter::encodeLDSTPtrReg(
const MCInst &MI,
unsigned OpNo,
113 SmallVectorImpl<MCFixup> &Fixups,
114 const MCSubtargetInfo &STI)
const {
115 auto MO = MI.getOperand(OpNo);
120 switch (MO.getReg()) {
121 case AVR::R27R26:
return 0x03;
122 case AVR::R29R28:
return 0x02;
123 case AVR::R31R30:
return 0x00;
133 unsigned AVRMCCodeEmitter::encodeMemri(
const MCInst &MI,
unsigned OpNo,
134 SmallVectorImpl<MCFixup> &Fixups,
135 const MCSubtargetInfo &STI)
const {
136 auto RegOp = MI.getOperand(OpNo);
137 auto OffsetOp = MI.getOperand(OpNo + 1);
139 assert(RegOp.isReg() &&
"Expected register operand");
143 switch (RegOp.getReg()) {
156 if (OffsetOp.isImm()) {
157 OffsetBits = OffsetOp.getImm();
158 }
else if (OffsetOp.isExpr()) {
166 return (RegBit << 6) | OffsetBits;
169 unsigned AVRMCCodeEmitter::encodeComplement(
const MCInst &MI,
unsigned OpNo,
170 SmallVectorImpl<MCFixup> &Fixups,
171 const MCSubtargetInfo &STI)
const {
173 assert(MI.getOperand(OpNo).isImm());
175 auto Imm = MI.getOperand(OpNo).getImm();
179 template <AVR::Fixups Fixup>
180 unsigned AVRMCCodeEmitter::encodeImm(
const MCInst &MI,
unsigned OpNo,
181 SmallVectorImpl<MCFixup> &Fixups,
182 const MCSubtargetInfo &STI)
const {
183 auto MO = MI.getOperand(OpNo);
186 if (isa<AVRMCExpr>(MO.getExpr())) {
191 return getExprOpValue(MO.getExpr(),
Fixups, STI);
204 unsigned AVRMCCodeEmitter::encodeCallTarget(
const MCInst &MI,
unsigned OpNo,
205 SmallVectorImpl<MCFixup> &Fixups,
206 const MCSubtargetInfo &STI)
const {
207 auto MO = MI.getOperand(OpNo);
217 auto Target = MO.getImm();
222 unsigned AVRMCCodeEmitter::getExprOpValue(
const MCExpr *Expr,
223 SmallVectorImpl<MCFixup> &Fixups,
224 const MCSubtargetInfo &STI)
const {
229 Expr =
static_cast<const MCBinaryExpr *
>(Expr)->getLHS();
230 Kind = Expr->getKind();
234 AVRMCExpr
const *AVRExpr = cast<AVRMCExpr>(Expr);
236 if (AVRExpr->evaluateAsConstant(Result)) {
249 unsigned AVRMCCodeEmitter::getMachineOpValue(
const MCInst &MI,
251 SmallVectorImpl<MCFixup> &Fixups,
252 const MCSubtargetInfo &STI)
const {
254 if (MO.isImm())
return static_cast<unsigned>(MO.getImm());
257 return static_cast<unsigned>(
APFloat(MO.getFPImm())
265 return getExprOpValue(MO.getExpr(),
Fixups, STI);
268 void AVRMCCodeEmitter::emitInstruction(uint64_t Val,
unsigned Size,
269 const MCSubtargetInfo &STI,
270 raw_ostream &OS)
const {
271 const uint16_t *Words =
reinterpret_cast<uint16_t
const *
>(&Val);
272 size_t WordCount = Size / 2;
274 for (int64_t
i = WordCount - 1;
i >= 0; --
i) {
275 uint16_t
Word = Words[
i];
277 OS << (uint8_t) ((Word & 0x00ff) >> 0);
278 OS << (uint8_t) ((Word & 0xff00) >> 8);
282 void AVRMCCodeEmitter::encodeInstruction(
const MCInst &MI, raw_ostream &OS,
283 SmallVectorImpl<MCFixup> &Fixups,
284 const MCSubtargetInfo &STI)
const {
285 const MCInstrDesc &
Desc = MCII.
get(MI.getOpcode());
288 unsigned Size = Desc.getSize();
290 assert(Size > 0 &&
"Instruction size cannot be zero");
292 uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);
293 emitInstruction(BinaryOpCode, Size, STI, OS);
302 #include "AVRGenMCCodeEmitter.inc"
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
MCCodeEmitter * createAVRMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
Creates a machine code emitter for AVR.
Context object for machine code objects.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
unsigned const MachineRegisterInfo * MRI
MCCodeEmitter - Generic instruction encoding interface.
Interface to description of machine instruction set.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Lanai::Fixups FixupKind(const MCExpr *Expr)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
PowerPC TLS Dynamic Call Fixup
Writes AVR machine code to a stream.
static const char * Target
void adjustBranchTarget(T &val)
Adjusts the value of a branch target.
const MCRegisterInfo * getRegisterInfo() const
References to labels and assigned expressions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
A 22-bit fixup for the target of a CALL k or JMP k instruction.
Target specific expression.