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_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 if (MI->getOpcode() == Hexagon::PATCHABLE_FUNCTION_ENTER) { 108 AP.EmitSled(*MI, HexagonAsmPrinter::SledKind::FUNCTION_ENTER); 109 return; 110 } 111 if (MI->getOpcode() == Hexagon::PATCHABLE_FUNCTION_EXIT) { 112 AP.EmitSled(*MI, HexagonAsmPrinter::SledKind::FUNCTION_EXIT); 113 return; 114 } 115 if (MI->getOpcode() == Hexagon::PATCHABLE_TAIL_CALL) { 116 AP.EmitSled(*MI, HexagonAsmPrinter::SledKind::TAIL_CALL); 117 return; 118 } 119 120 MCInst *MCI = AP.OutContext.createMCInst(); 121 MCI->setOpcode(MI->getOpcode()); 122 assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) && 123 "MCI opcode should have been set on construction"); 124 125 for (const MachineOperand &MO : MI->operands()) { 126 MCOperand MCO; 127 bool MustExtend = MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended; 128 129 switch (MO.getType()) { 130 default: 131 MI->print(errs()); 132 llvm_unreachable("unknown operand type"); 133 case MachineOperand::MO_RegisterMask: 134 continue; 135 case MachineOperand::MO_Register: 136 // Ignore all implicit register operands. 137 if (MO.isImplicit()) 138 continue; 139 MCO = MCOperand::createReg(MO.getReg()); 140 break; 141 case MachineOperand::MO_FPImmediate: { 142 APFloat Val = MO.getFPImm()->getValueAPF(); 143 // FP immediates are used only when setting GPRs, so they may be dealt 144 // with like regular immediates from this point on. 145 auto Expr = HexagonMCExpr::create( 146 MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(), 147 AP.OutContext), 148 AP.OutContext); 149 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 150 MCO = MCOperand::createExpr(Expr); 151 break; 152 } 153 case MachineOperand::MO_Immediate: { 154 auto Expr = HexagonMCExpr::create( 155 MCConstantExpr::create(MO.getImm(), AP.OutContext), AP.OutContext); 156 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 157 MCO = MCOperand::createExpr(Expr); 158 break; 159 } 160 case MachineOperand::MO_MachineBasicBlock: { 161 MCExpr const *Expr = MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), 162 AP.OutContext); 163 Expr = HexagonMCExpr::create(Expr, AP.OutContext); 164 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend); 165 MCO = MCOperand::createExpr(Expr); 166 break; 167 } 168 case MachineOperand::MO_GlobalAddress: 169 MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP, MustExtend); 170 break; 171 case MachineOperand::MO_ExternalSymbol: 172 MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), 173 AP, MustExtend); 174 break; 175 case MachineOperand::MO_JumpTableIndex: 176 MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, MustExtend); 177 break; 178 case MachineOperand::MO_ConstantPoolIndex: 179 MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, MustExtend); 180 break; 181 case MachineOperand::MO_BlockAddress: 182 MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP, 183 MustExtend); 184 break; 185 } 186 187 MCI->addOperand(MCO); 188 } 189 AP.HexagonProcessInstruction(*MCI, *MI); 190 HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI); 191 MCB.addOperand(MCOperand::createInst(MCI)); 192 } 193