1 //===- HexagonMCInstLower.cpp - Convert Hexagon MachineInstr to an MCInst -===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains code to lower Hexagon MachineInstrs to their corresponding 11 // MCInst records. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "Hexagon.h" 16 #include "HexagonAsmPrinter.h" 17 #include "HexagonMachineFunctionInfo.h" 18 #include "MCTargetDesc/HexagonMCInstrInfo.h" 19 20 #include "llvm/CodeGen/MachineBasicBlock.h" 21 #include "llvm/IR/Constants.h" 22 #include "llvm/IR/Mangler.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCExpr.h" 25 #include "llvm/MC/MCInst.h" 26 27 using namespace llvm; 28 29 namespace llvm { 30 void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, 31 MCInst &MCB, HexagonAsmPrinter &AP); 32 } 33 34 static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, 35 HexagonAsmPrinter &Printer, bool MustExtend) { 36 MCContext &MC = Printer.OutContext; 37 const MCExpr *ME; 38 39 // Populate the relocation type based on Hexagon target flags 40 // set on an operand 41 MCSymbolRefExpr::VariantKind RelocationType; 42 switch (MO.getTargetFlags()) { 43 default: 44 RelocationType = MCSymbolRefExpr::VK_None; 45 break; 46 case HexagonII::MO_PCREL: 47 RelocationType = MCSymbolRefExpr::VK_Hexagon_PCREL; 48 break; 49 case HexagonII::MO_GOT: 50 RelocationType = MCSymbolRefExpr::VK_GOT; 51 break; 52 case HexagonII::MO_LO16: 53 RelocationType = MCSymbolRefExpr::VK_Hexagon_LO16; 54 break; 55 case HexagonII::MO_HI16: 56 RelocationType = MCSymbolRefExpr::VK_Hexagon_HI16; 57 break; 58 case HexagonII::MO_GPREL: 59 RelocationType = MCSymbolRefExpr::VK_Hexagon_GPREL; 60 break; 61 case HexagonII::MO_GDGOT: 62 RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_GOT; 63 break; 64 case HexagonII::MO_GDPLT: 65 RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_PLT; 66 break; 67 case HexagonII::MO_IE: 68 RelocationType = MCSymbolRefExpr::VK_Hexagon_IE; 69 break; 70 case HexagonII::MO_IEGOT: 71 RelocationType = MCSymbolRefExpr::VK_Hexagon_IE_GOT; 72 break; 73 case HexagonII::MO_TPREL: 74 RelocationType = MCSymbolRefExpr::VK_TPREL; 75 break; 76 } 77 78 ME = MCSymbolRefExpr::create(Symbol, RelocationType, MC); 79 80 if (!MO.isJTI() && MO.getOffset()) 81 ME = MCBinaryExpr::createAdd(ME, MCConstantExpr::create(MO.getOffset(), MC), 82 MC); 83 84 ME = HexagonMCExpr::create(ME, MC); 85 HexagonMCInstrInfo::setMustExtend(*ME, MustExtend); 86 return MCOperand::createExpr(ME); 87 } 88 89 // Create an MCInst from a MachineInstr 90 void llvm::HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, 91 MCInst &MCB, HexagonAsmPrinter &AP) { 92 if (MI->getOpcode() == Hexagon::ENDLOOP0) { 93 HexagonMCInstrInfo::setInnerLoop(MCB); 94 return; 95 } 96 if (MI->getOpcode() == Hexagon::ENDLOOP1) { 97 HexagonMCInstrInfo::setOuterLoop(MCB); 98 return; 99 } 100 MCInst *MCI = new (AP.OutContext) MCInst; 101 MCI->setOpcode(MI->getOpcode()); 102 assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) && 103 "MCI opcode should have been set on construction"); 104 105 for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) { 106 const MachineOperand &MO = MI->getOperand(i); 107 MCOperand MCO; 108 bool MustExtend = MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended; 109 110 switch (MO.getType()) { 111 default: 112 MI->dump(); 113 llvm_unreachable("unknown operand type"); 114 case MachineOperand::MO_Register: 115 // Ignore all implicit register operands. 116 if (MO.isImplicit()) continue; 117 MCO = MCOperand::createReg(MO.getReg()); 118 break; 119 case MachineOperand::MO_FPImmediate: { 120 APFloat Val = MO.getFPImm()->getValueAPF(); 121 // FP immediates are used only when setting GPRs, so they may be dealt 122 // with like regular immediates from this point on. 123 auto Expr = HexagonMCExpr::create( 124 MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(), 125 AP.OutContext), 126 AP.OutContext); 127 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 128 MCO = MCOperand::createExpr(Expr); 129 break; 130 } 131 case MachineOperand::MO_Immediate: { 132 auto Expr = HexagonMCExpr::create( 133 MCConstantExpr::create(MO.getImm(), AP.OutContext), AP.OutContext); 134 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 135 MCO = MCOperand::createExpr(Expr); 136 break; 137 } 138 case MachineOperand::MO_MachineBasicBlock: { 139 MCExpr const *Expr = MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), 140 AP.OutContext); 141 Expr = HexagonMCExpr::create(Expr, AP.OutContext); 142 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 143 MCO = MCOperand::createExpr(Expr); 144 break; 145 } 146 case MachineOperand::MO_GlobalAddress: 147 MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP, MustExtend); 148 break; 149 case MachineOperand::MO_ExternalSymbol: 150 MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), 151 AP, MustExtend); 152 break; 153 case MachineOperand::MO_JumpTableIndex: 154 MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, MustExtend); 155 break; 156 case MachineOperand::MO_ConstantPoolIndex: 157 MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, MustExtend); 158 break; 159 case MachineOperand::MO_BlockAddress: 160 MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP, 161 MustExtend); 162 break; 163 } 164 165 MCI->addOperand(MCO); 166 } 167 AP.HexagonProcessInstruction(*MCI, *MI); 168 HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI); 169 MCB.addOperand(MCOperand::createInst(MCI)); 170 } 171