1 //===- HexagonMCInstLower.cpp - Convert Hexagon 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 Hexagon MachineInstrs to their corresponding
12 //===----------------------------------------------------------------------===//
15 #include "HexagonAsmPrinter.h"
16 #include "MCTargetDesc/HexagonMCExpr.h"
17 #include "MCTargetDesc/HexagonMCInstrInfo.h"
18 #include "MCTargetDesc/HexagonMCTargetDesc.h"
19 #include "llvm/ADT/APFloat.h"
20 #include "llvm/ADT/APInt.h"
21 #include "llvm/CodeGen/MachineBasicBlock.h"
22 #include "llvm/CodeGen/MachineInstr.h"
23 #include "llvm/CodeGen/MachineOperand.h"
24 #include "llvm/IR/Constants.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCExpr.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/raw_ostream.h"
36 void HexagonLowerToMC(const MCInstrInfo
&MCII
, const MachineInstr
*MI
,
37 MCInst
&MCB
, HexagonAsmPrinter
&AP
);
39 } // end namespace llvm
41 static MCOperand
GetSymbolRef(const MachineOperand
&MO
, const MCSymbol
*Symbol
,
42 HexagonAsmPrinter
&Printer
, bool MustExtend
) {
43 MCContext
&MC
= Printer
.OutContext
;
46 // Populate the relocation type based on Hexagon target flags
48 MCSymbolRefExpr::VariantKind RelocationType
;
49 switch (MO
.getTargetFlags() & ~HexagonII::HMOTF_ConstExtended
) {
51 RelocationType
= MCSymbolRefExpr::VK_None
;
53 case HexagonII::MO_PCREL
:
54 RelocationType
= MCSymbolRefExpr::VK_Hexagon_PCREL
;
56 case HexagonII::MO_GOT
:
57 RelocationType
= MCSymbolRefExpr::VK_GOT
;
59 case HexagonII::MO_LO16
:
60 RelocationType
= MCSymbolRefExpr::VK_Hexagon_LO16
;
62 case HexagonII::MO_HI16
:
63 RelocationType
= MCSymbolRefExpr::VK_Hexagon_HI16
;
65 case HexagonII::MO_GPREL
:
66 RelocationType
= MCSymbolRefExpr::VK_Hexagon_GPREL
;
68 case HexagonII::MO_GDGOT
:
69 RelocationType
= MCSymbolRefExpr::VK_Hexagon_GD_GOT
;
71 case HexagonII::MO_GDPLT
:
72 RelocationType
= MCSymbolRefExpr::VK_Hexagon_GD_PLT
;
74 case HexagonII::MO_IE
:
75 RelocationType
= MCSymbolRefExpr::VK_Hexagon_IE
;
77 case HexagonII::MO_IEGOT
:
78 RelocationType
= MCSymbolRefExpr::VK_Hexagon_IE_GOT
;
80 case HexagonII::MO_TPREL
:
81 RelocationType
= MCSymbolRefExpr::VK_TPREL
;
85 ME
= MCSymbolRefExpr::create(Symbol
, RelocationType
, MC
);
87 if (!MO
.isJTI() && MO
.getOffset())
88 ME
= MCBinaryExpr::createAdd(ME
, MCConstantExpr::create(MO
.getOffset(), MC
),
91 ME
= HexagonMCExpr::create(ME
, MC
);
92 HexagonMCInstrInfo::setMustExtend(*ME
, MustExtend
);
93 return MCOperand::createExpr(ME
);
96 // Create an MCInst from a MachineInstr
97 void llvm::HexagonLowerToMC(const MCInstrInfo
&MCII
, const MachineInstr
*MI
,
98 MCInst
&MCB
, HexagonAsmPrinter
&AP
) {
99 if (MI
->getOpcode() == Hexagon::ENDLOOP0
) {
100 HexagonMCInstrInfo::setInnerLoop(MCB
);
103 if (MI
->getOpcode() == Hexagon::ENDLOOP1
) {
104 HexagonMCInstrInfo::setOuterLoop(MCB
);
107 MCInst
*MCI
= new (AP
.OutContext
) MCInst
;
108 MCI
->setOpcode(MI
->getOpcode());
109 assert(MCI
->getOpcode() == static_cast<unsigned>(MI
->getOpcode()) &&
110 "MCI opcode should have been set on construction");
112 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
< e
; i
++) {
113 const MachineOperand
&MO
= MI
->getOperand(i
);
115 bool MustExtend
= MO
.getTargetFlags() & HexagonII::HMOTF_ConstExtended
;
117 switch (MO
.getType()) {
120 llvm_unreachable("unknown operand type");
121 case MachineOperand::MO_RegisterMask
:
123 case MachineOperand::MO_Register
:
124 // Ignore all implicit register operands.
127 MCO
= MCOperand::createReg(MO
.getReg());
129 case MachineOperand::MO_FPImmediate
: {
130 APFloat Val
= MO
.getFPImm()->getValueAPF();
131 // FP immediates are used only when setting GPRs, so they may be dealt
132 // with like regular immediates from this point on.
133 auto Expr
= HexagonMCExpr::create(
134 MCConstantExpr::create(*Val
.bitcastToAPInt().getRawData(),
137 HexagonMCInstrInfo::setMustExtend(*Expr
, MustExtend
);
138 MCO
= MCOperand::createExpr(Expr
);
141 case MachineOperand::MO_Immediate
: {
142 auto Expr
= HexagonMCExpr::create(
143 MCConstantExpr::create(MO
.getImm(), AP
.OutContext
), AP
.OutContext
);
144 HexagonMCInstrInfo::setMustExtend(*Expr
, MustExtend
);
145 MCO
= MCOperand::createExpr(Expr
);
148 case MachineOperand::MO_MachineBasicBlock
: {
149 MCExpr
const *Expr
= MCSymbolRefExpr::create(MO
.getMBB()->getSymbol(),
151 Expr
= HexagonMCExpr::create(Expr
, AP
.OutContext
);
152 HexagonMCInstrInfo::setMustExtend(*Expr
, MustExtend
);
153 MCO
= MCOperand::createExpr(Expr
);
156 case MachineOperand::MO_GlobalAddress
:
157 MCO
= GetSymbolRef(MO
, AP
.getSymbol(MO
.getGlobal()), AP
, MustExtend
);
159 case MachineOperand::MO_ExternalSymbol
:
160 MCO
= GetSymbolRef(MO
, AP
.GetExternalSymbolSymbol(MO
.getSymbolName()),
163 case MachineOperand::MO_JumpTableIndex
:
164 MCO
= GetSymbolRef(MO
, AP
.GetJTISymbol(MO
.getIndex()), AP
, MustExtend
);
166 case MachineOperand::MO_ConstantPoolIndex
:
167 MCO
= GetSymbolRef(MO
, AP
.GetCPISymbol(MO
.getIndex()), AP
, MustExtend
);
169 case MachineOperand::MO_BlockAddress
:
170 MCO
= GetSymbolRef(MO
, AP
.GetBlockAddressSymbol(MO
.getBlockAddress()), AP
,
175 MCI
->addOperand(MCO
);
177 AP
.HexagonProcessInstruction(*MCI
, *MI
);
178 HexagonMCInstrInfo::extendIfNeeded(AP
.OutContext
, MCII
, MCB
, *MCI
);
179 MCB
.addOperand(MCOperand::createInst(MCI
));