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) { 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 return MCOperand::createExpr(HexagonMCExpr::create(ME, MC)); 85 } 86 87 // Create an MCInst from a MachineInstr 88 void llvm::HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, 89 MCInst &MCB, HexagonAsmPrinter &AP) { 90 if (MI->getOpcode() == Hexagon::ENDLOOP0) { 91 HexagonMCInstrInfo::setInnerLoop(MCB); 92 return; 93 } 94 if (MI->getOpcode() == Hexagon::ENDLOOP1) { 95 HexagonMCInstrInfo::setOuterLoop(MCB); 96 return; 97 } 98 MCInst *MCI = new (AP.OutContext) MCInst; 99 MCI->setOpcode(MI->getOpcode()); 100 assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) && 101 "MCI opcode should have been set on construction"); 102 bool MustExtend = false; 103 104 for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) { 105 const MachineOperand &MO = MI->getOperand(i); 106 MCOperand MCO; 107 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended) 108 MustExtend = true; 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 MCO = MCOperand::createExpr( 124 HexagonMCExpr::create(MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(), 125 AP.OutContext), AP.OutContext)); 126 break; 127 } 128 case MachineOperand::MO_Immediate: 129 MCO = MCOperand::createExpr( 130 HexagonMCExpr::create(MCConstantExpr::create(MO.getImm(), AP.OutContext), AP.OutContext)); 131 break; 132 case MachineOperand::MO_MachineBasicBlock: 133 MCO = MCOperand::createExpr 134 (HexagonMCExpr::create(MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), 135 AP.OutContext), AP.OutContext)); 136 break; 137 case MachineOperand::MO_GlobalAddress: 138 MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP); 139 break; 140 case MachineOperand::MO_ExternalSymbol: 141 MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), 142 AP); 143 break; 144 case MachineOperand::MO_JumpTableIndex: 145 MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP); 146 break; 147 case MachineOperand::MO_ConstantPoolIndex: 148 MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP); 149 break; 150 case MachineOperand::MO_BlockAddress: 151 MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP); 152 break; 153 } 154 155 MCI->addOperand(MCO); 156 } 157 AP.HexagonProcessInstruction(*MCI, *MI); 158 HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI, 159 MustExtend); 160 MCB.addOperand(MCOperand::createInst(MCI)); 161 } 162