1 //===-- AVRMCInstLower.cpp - Convert AVR MachineInstr to an MCInst --------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains code to lower AVR MachineInstrs to their corresponding
12 //===----------------------------------------------------------------------===//
14 #include "AVRMCInstLower.h"
15 #include "AVRInstrInfo.h"
16 #include "MCTargetDesc/AVRMCExpr.h"
18 #include "llvm/CodeGen/AsmPrinter.h"
19 #include "llvm/IR/Mangler.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/Support/ErrorHandling.h"
26 AVRMCInstLower::lowerSymbolOperand(const MachineOperand
&MO
, MCSymbol
*Sym
,
27 const AVRSubtarget
&Subtarget
) const {
28 unsigned char TF
= MO
.getTargetFlags();
29 const MCExpr
*Expr
= MCSymbolRefExpr::create(Sym
, Ctx
);
31 bool IsNegated
= false;
32 if (TF
& AVRII::MO_NEG
) {
36 if (!MO
.isJTI() && MO
.getOffset()) {
37 Expr
= MCBinaryExpr::createAdd(
38 Expr
, MCConstantExpr::create(MO
.getOffset(), Ctx
), Ctx
);
41 bool IsFunction
= MO
.isGlobal() && isa
<Function
>(MO
.getGlobal());
43 if (TF
& AVRII::MO_LO
) {
46 AVRMCExpr::create(Subtarget
.hasEIJMPCALL() ? AVRMCExpr::VK_AVR_LO8_GS
47 : AVRMCExpr::VK_AVR_PM_LO8
,
48 Expr
, IsNegated
, Ctx
);
50 Expr
= AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8
, Expr
, IsNegated
, Ctx
);
52 } else if (TF
& AVRII::MO_HI
) {
55 AVRMCExpr::create(Subtarget
.hasEIJMPCALL() ? AVRMCExpr::VK_AVR_HI8_GS
56 : AVRMCExpr::VK_AVR_PM_HI8
,
57 Expr
, IsNegated
, Ctx
);
59 Expr
= AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8
, Expr
, IsNegated
, Ctx
);
62 llvm_unreachable("Unknown target flag on symbol operand");
65 return MCOperand::createExpr(Expr
);
68 void AVRMCInstLower::lowerInstruction(const MachineInstr
&MI
,
69 MCInst
&OutMI
) const {
70 auto &Subtarget
= MI
.getParent()->getParent()->getSubtarget
<AVRSubtarget
>();
71 OutMI
.setOpcode(MI
.getOpcode());
73 for (MachineOperand
const &MO
: MI
.operands()) {
76 switch (MO
.getType()) {
79 llvm_unreachable("unknown operand type");
80 case MachineOperand::MO_Register
:
81 // Ignore all implicit register operands.
84 MCOp
= MCOperand::createReg(MO
.getReg());
86 case MachineOperand::MO_Immediate
:
87 MCOp
= MCOperand::createImm(MO
.getImm());
89 case MachineOperand::MO_GlobalAddress
:
91 lowerSymbolOperand(MO
, Printer
.getSymbol(MO
.getGlobal()), Subtarget
);
93 case MachineOperand::MO_ExternalSymbol
:
94 MCOp
= lowerSymbolOperand(
95 MO
, Printer
.GetExternalSymbolSymbol(MO
.getSymbolName()), Subtarget
);
97 case MachineOperand::MO_MachineBasicBlock
:
98 MCOp
= MCOperand::createExpr(
99 MCSymbolRefExpr::create(MO
.getMBB()->getSymbol(), Ctx
));
101 case MachineOperand::MO_RegisterMask
:
103 case MachineOperand::MO_BlockAddress
:
104 MCOp
= lowerSymbolOperand(
105 MO
, Printer
.GetBlockAddressSymbol(MO
.getBlockAddress()), Subtarget
);
107 case MachineOperand::MO_JumpTableIndex
:
108 MCOp
= lowerSymbolOperand(MO
, Printer
.GetJTISymbol(MO
.getIndex()),
111 case MachineOperand::MO_ConstantPoolIndex
:
112 MCOp
= lowerSymbolOperand(MO
, Printer
.GetCPISymbol(MO
.getIndex()),
117 OutMI
.addOperand(MCOp
);
121 } // end of namespace llvm