192 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains code to lower Hexagon MachineInstrs to their corresponding10// 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 31using namespace llvm;32 33namespace llvm {34 35void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,36 MCInst &MCB, HexagonAsmPrinter &AP);37 38} // end namespace llvm39 40static 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 flags46 // set on an operand47 HexagonMCExpr::VariantKind RelocationType;48 switch (MO.getTargetFlags() & ~HexagonII::HMOTF_ConstExtended) {49 default:50 RelocationType = HexagonMCExpr::VK_None;51 break;52 case HexagonII::MO_PCREL:53 RelocationType = HexagonMCExpr::VK_PCREL;54 break;55 case HexagonII::MO_GOT:56 RelocationType = HexagonMCExpr::VK_GOT;57 break;58 case HexagonII::MO_LO16:59 RelocationType = HexagonMCExpr::VK_LO16;60 break;61 case HexagonII::MO_HI16:62 RelocationType = HexagonMCExpr::VK_HI16;63 break;64 case HexagonII::MO_GPREL:65 RelocationType = HexagonMCExpr::VK_GPREL;66 break;67 case HexagonII::MO_GDGOT:68 RelocationType = HexagonMCExpr::VK_GD_GOT;69 break;70 case HexagonII::MO_GDPLT:71 RelocationType = HexagonMCExpr::VK_GD_PLT;72 break;73 case HexagonII::MO_IE:74 RelocationType = HexagonMCExpr::VK_IE;75 break;76 case HexagonII::MO_IEGOT:77 RelocationType = HexagonMCExpr::VK_IE_GOT;78 break;79 case HexagonII::MO_TPREL:80 RelocationType = HexagonMCExpr::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 MachineInstr96void 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 dealt143 // 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