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