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