1 //===- HexagonMCInstLower.cpp - Convert Hexagon MachineInstr to an MCInst -===// 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 contains code to lower Hexagon MachineInstrs to their corresponding 10 // MCInst records. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Hexagon.h" 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" 30 #include <cassert> 31 32 using namespace llvm; 33 34 namespace llvm { 35 36 void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, 37 MCInst &MCB, HexagonAsmPrinter &AP); 38 39 } // end namespace llvm 40 41 static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, 42 HexagonAsmPrinter &Printer, bool MustExtend) { 43 MCContext &MC = Printer.OutContext; 44 const MCExpr *ME; 45 46 // Populate the relocation type based on Hexagon target flags 47 // set on an operand 48 MCSymbolRefExpr::VariantKind RelocationType; 49 switch (MO.getTargetFlags() & ~HexagonII::HMOTF_ConstExtended) { 50 default: 51 RelocationType = MCSymbolRefExpr::VK_None; 52 break; 53 case HexagonII::MO_PCREL: 54 RelocationType = MCSymbolRefExpr::VK_Hexagon_PCREL; 55 break; 56 case HexagonII::MO_GOT: 57 RelocationType = MCSymbolRefExpr::VK_GOT; 58 break; 59 case HexagonII::MO_LO16: 60 RelocationType = MCSymbolRefExpr::VK_Hexagon_LO16; 61 break; 62 case HexagonII::MO_HI16: 63 RelocationType = MCSymbolRefExpr::VK_Hexagon_HI16; 64 break; 65 case HexagonII::MO_GPREL: 66 RelocationType = MCSymbolRefExpr::VK_Hexagon_GPREL; 67 break; 68 case HexagonII::MO_GDGOT: 69 RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_GOT; 70 break; 71 case HexagonII::MO_GDPLT: 72 RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_PLT; 73 break; 74 case HexagonII::MO_IE: 75 RelocationType = MCSymbolRefExpr::VK_Hexagon_IE; 76 break; 77 case HexagonII::MO_IEGOT: 78 RelocationType = MCSymbolRefExpr::VK_Hexagon_IE_GOT; 79 break; 80 case HexagonII::MO_TPREL: 81 RelocationType = MCSymbolRefExpr::VK_TPREL; 82 break; 83 } 84 85 ME = MCSymbolRefExpr::create(Symbol, RelocationType, MC); 86 87 if (!MO.isJTI() && MO.getOffset()) 88 ME = MCBinaryExpr::createAdd(ME, MCConstantExpr::create(MO.getOffset(), MC), 89 MC); 90 91 ME = HexagonMCExpr::create(ME, MC); 92 HexagonMCInstrInfo::setMustExtend(*ME, MustExtend); 93 return MCOperand::createExpr(ME); 94 } 95 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); 101 return; 102 } 103 if (MI->getOpcode() == Hexagon::ENDLOOP1) { 104 HexagonMCInstrInfo::setOuterLoop(MCB); 105 return; 106 } 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"); 111 112 for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) { 113 const MachineOperand &MO = MI->getOperand(i); 114 MCOperand MCO; 115 bool MustExtend = MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended; 116 117 switch (MO.getType()) { 118 default: 119 MI->print(errs()); 120 llvm_unreachable("unknown operand type"); 121 case MachineOperand::MO_RegisterMask: 122 continue; 123 case MachineOperand::MO_Register: 124 // Ignore all implicit register operands. 125 if (MO.isImplicit()) 126 continue; 127 MCO = MCOperand::createReg(MO.getReg()); 128 break; 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(), 135 AP.OutContext), 136 AP.OutContext); 137 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 138 MCO = MCOperand::createExpr(Expr); 139 break; 140 } 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); 146 break; 147 } 148 case MachineOperand::MO_MachineBasicBlock: { 149 MCExpr const *Expr = MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), 150 AP.OutContext); 151 Expr = HexagonMCExpr::create(Expr, AP.OutContext); 152 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 153 MCO = MCOperand::createExpr(Expr); 154 break; 155 } 156 case MachineOperand::MO_GlobalAddress: 157 MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP, MustExtend); 158 break; 159 case MachineOperand::MO_ExternalSymbol: 160 MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), 161 AP, MustExtend); 162 break; 163 case MachineOperand::MO_JumpTableIndex: 164 MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, MustExtend); 165 break; 166 case MachineOperand::MO_ConstantPoolIndex: 167 MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, MustExtend); 168 break; 169 case MachineOperand::MO_BlockAddress: 170 MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP, 171 MustExtend); 172 break; 173 } 174 175 MCI->addOperand(MCO); 176 } 177 AP.HexagonProcessInstruction(*MCI, *MI); 178 HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI); 179 MCB.addOperand(MCOperand::createInst(MCI)); 180 } 181