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"
16 #include "AVRInstrInfo.h"
17 #include "MCTargetDesc/AVRMCExpr.h"
19 #include "llvm/CodeGen/AsmPrinter.h"
20 #include "llvm/IR/Mangler.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/Support/ErrorHandling.h"
26 MCOperand
AVRMCInstLower::lowerSymbolOperand(const MachineOperand
&MO
,
27 MCSymbol
*Sym
) 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
) { IsNegated
= true; }
34 if (!MO
.isJTI() && MO
.getOffset()) {
35 Expr
= MCBinaryExpr::createAdd(
36 Expr
, MCConstantExpr::create(MO
.getOffset(), Ctx
), Ctx
);
39 bool IsFunction
= MO
.isGlobal() && isa
<Function
>(MO
.getGlobal());
41 if (TF
& AVRII::MO_LO
) {
43 // N.B. Should we use _GS fixups here to cope with >128k progmem?
44 Expr
= AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8
, Expr
, IsNegated
, Ctx
);
46 Expr
= AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8
, Expr
, IsNegated
, Ctx
);
48 } else if (TF
& AVRII::MO_HI
) {
50 // N.B. Should we use _GS fixups here to cope with >128k progmem?
51 Expr
= AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8
, Expr
, IsNegated
, Ctx
);
53 Expr
= AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8
, Expr
, IsNegated
, Ctx
);
56 llvm_unreachable("Unknown target flag on symbol operand");
59 return MCOperand::createExpr(Expr
);
62 void AVRMCInstLower::lowerInstruction(const MachineInstr
&MI
, MCInst
&OutMI
) const {
63 OutMI
.setOpcode(MI
.getOpcode());
65 for (MachineOperand
const &MO
: MI
.operands()) {
68 switch (MO
.getType()) {
71 llvm_unreachable("unknown operand type");
72 case MachineOperand::MO_Register
:
73 // Ignore all implicit register operands.
76 MCOp
= MCOperand::createReg(MO
.getReg());
78 case MachineOperand::MO_Immediate
:
79 MCOp
= MCOperand::createImm(MO
.getImm());
81 case MachineOperand::MO_GlobalAddress
:
82 MCOp
= lowerSymbolOperand(MO
, Printer
.getSymbol(MO
.getGlobal()));
84 case MachineOperand::MO_ExternalSymbol
:
85 MCOp
= lowerSymbolOperand(
86 MO
, Printer
.GetExternalSymbolSymbol(MO
.getSymbolName()));
88 case MachineOperand::MO_MachineBasicBlock
:
89 MCOp
= MCOperand::createExpr(
90 MCSymbolRefExpr::create(MO
.getMBB()->getSymbol(), Ctx
));
92 case MachineOperand::MO_RegisterMask
:
94 case MachineOperand::MO_BlockAddress
:
95 MCOp
= lowerSymbolOperand(
96 MO
, Printer
.GetBlockAddressSymbol(MO
.getBlockAddress()));
98 case MachineOperand::MO_JumpTableIndex
:
99 MCOp
= lowerSymbolOperand(MO
, Printer
.GetJTISymbol(MO
.getIndex()));
101 case MachineOperand::MO_ConstantPoolIndex
:
102 MCOp
= lowerSymbolOperand(MO
, Printer
.GetCPISymbol(MO
.getIndex()));
106 OutMI
.addOperand(MCOp
);
110 } // end of namespace llvm