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 } 62 63 ME = MCSymbolRefExpr::create(Symbol, RelocationType, MC); 64 65 if (!MO.isJTI() && MO.getOffset()) 66 ME = MCBinaryExpr::createAdd(ME, MCConstantExpr::create(MO.getOffset(), MC), 67 MC); 68 69 return MCOperand::createExpr(ME); 70 } 71 72 // Create an MCInst from a MachineInstr 73 void llvm::HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, 74 MCInst &MCB, HexagonAsmPrinter &AP) { 75 if (MI->getOpcode() == Hexagon::ENDLOOP0) { 76 HexagonMCInstrInfo::setInnerLoop(MCB); 77 return; 78 } 79 if (MI->getOpcode() == Hexagon::ENDLOOP1) { 80 HexagonMCInstrInfo::setOuterLoop(MCB); 81 return; 82 } 83 MCInst *MCI = new (AP.OutContext) MCInst; 84 MCI->setOpcode(MI->getOpcode()); 85 assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) && 86 "MCI opcode should have been set on construction"); 87 bool MustExtend = false; 88 89 for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) { 90 const MachineOperand &MO = MI->getOperand(i); 91 MCOperand MCO; 92 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended) 93 MustExtend = true; 94 95 switch (MO.getType()) { 96 default: 97 MI->dump(); 98 llvm_unreachable("unknown operand type"); 99 case MachineOperand::MO_Register: 100 // Ignore all implicit register operands. 101 if (MO.isImplicit()) continue; 102 MCO = MCOperand::createReg(MO.getReg()); 103 break; 104 case MachineOperand::MO_FPImmediate: { 105 APFloat Val = MO.getFPImm()->getValueAPF(); 106 // FP immediates are used only when setting GPRs, so they may be dealt 107 // with like regular immediates from this point on. 108 MCO = MCOperand::createExpr( 109 MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(), 110 AP.OutContext)); 111 break; 112 } 113 case MachineOperand::MO_Immediate: 114 MCO = MCOperand::createExpr( 115 MCConstantExpr::create(MO.getImm(), AP.OutContext)); 116 break; 117 case MachineOperand::MO_MachineBasicBlock: 118 MCO = MCOperand::createExpr 119 (MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), 120 AP.OutContext)); 121 break; 122 case MachineOperand::MO_GlobalAddress: 123 MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP); 124 break; 125 case MachineOperand::MO_ExternalSymbol: 126 MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), 127 AP); 128 break; 129 case MachineOperand::MO_JumpTableIndex: 130 MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP); 131 break; 132 case MachineOperand::MO_ConstantPoolIndex: 133 MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP); 134 break; 135 case MachineOperand::MO_BlockAddress: 136 MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP); 137 break; 138 } 139 140 MCI->addOperand(MCO); 141 } 142 AP.HexagonProcessInstruction(*MCI, *MI); 143 HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI, 144 MustExtend); 145 MCB.addOperand(MCOperand::createInst(MCI)); 146 } 147