Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
35271 views
//===- XtensaAsmPrinter.cpp Xtensa LLVM Assembly Printer ------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains a printer that converts from our internal representation9// of machine-dependent LLVM code to GAS-format Xtensa assembly language.10//11//===----------------------------------------------------------------------===//1213#include "XtensaAsmPrinter.h"14#include "MCTargetDesc/XtensaMCExpr.h"15#include "MCTargetDesc/XtensaTargetStreamer.h"16#include "TargetInfo/XtensaTargetInfo.h"17#include "XtensaConstantPoolValue.h"18#include "llvm/ADT/StringExtras.h"19#include "llvm/BinaryFormat/ELF.h"20#include "llvm/CodeGen/MachineConstantPool.h"21#include "llvm/CodeGen/MachineModuleInfoImpls.h"22#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"23#include "llvm/MC/MCExpr.h"24#include "llvm/MC/MCInstBuilder.h"25#include "llvm/MC/MCSectionELF.h"26#include "llvm/MC/MCStreamer.h"27#include "llvm/MC/MCSymbol.h"28#include "llvm/MC/MCSymbolELF.h"29#include "llvm/MC/TargetRegistry.h"3031using namespace llvm;3233static MCSymbolRefExpr::VariantKind34getModifierVariantKind(XtensaCP::XtensaCPModifier Modifier) {35switch (Modifier) {36case XtensaCP::no_modifier:37return MCSymbolRefExpr::VK_None;38case XtensaCP::TPOFF:39return MCSymbolRefExpr::VK_TPOFF;40}41report_fatal_error("Invalid XtensaCPModifier!");42}4344void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {45unsigned Opc = MI->getOpcode();4647switch (Opc) {48case Xtensa::BR_JT:49EmitToStreamer(50*OutStreamer,51MCInstBuilder(Xtensa::JX).addReg(MI->getOperand(0).getReg()));52return;53default:54MCInst LoweredMI;55lowerToMCInst(MI, LoweredMI);56EmitToStreamer(*OutStreamer, LoweredMI);57return;58}59}6061void XtensaAsmPrinter::emitMachineConstantPoolValue(62MachineConstantPoolValue *MCPV) {63XtensaConstantPoolValue *ACPV = static_cast<XtensaConstantPoolValue *>(MCPV);64MCSymbol *MCSym;6566if (ACPV->isBlockAddress()) {67const BlockAddress *BA =68cast<XtensaConstantPoolConstant>(ACPV)->getBlockAddress();69MCSym = GetBlockAddressSymbol(BA);70} else if (ACPV->isJumpTable()) {71unsigned Idx = cast<XtensaConstantPoolJumpTable>(ACPV)->getIndex();72MCSym = this->GetJTISymbol(Idx, false);73} else {74assert(ACPV->isExtSymbol() && "unrecognized constant pool value");75XtensaConstantPoolSymbol *XtensaSym = cast<XtensaConstantPoolSymbol>(ACPV);76const char *SymName = XtensaSym->getSymbol();7778if (XtensaSym->isPrivateLinkage()) {79const DataLayout &DL = getDataLayout();80MCSym = OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +81SymName);82} else {83MCSym = OutContext.getOrCreateSymbol(SymName);84}85}8687MCSymbol *LblSym = GetCPISymbol(ACPV->getLabelId());88auto *TS =89static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());90MCSymbolRefExpr::VariantKind VK = getModifierVariantKind(ACPV->getModifier());9192if (ACPV->getModifier() != XtensaCP::no_modifier) {93std::string SymName(MCSym->getName());94StringRef Modifier = ACPV->getModifierText();95SymName += Modifier;96MCSym = OutContext.getOrCreateSymbol(SymName);97}9899const MCExpr *Expr = MCSymbolRefExpr::create(MCSym, VK, OutContext);100TS->emitLiteral(LblSym, Expr, false);101}102103void XtensaAsmPrinter::emitMachineConstantPoolEntry(104const MachineConstantPoolEntry &CPE, int i) {105if (CPE.isMachineConstantPoolEntry()) {106XtensaConstantPoolValue *ACPV =107static_cast<XtensaConstantPoolValue *>(CPE.Val.MachineCPVal);108ACPV->setLabelId(i);109emitMachineConstantPoolValue(CPE.Val.MachineCPVal);110} else {111MCSymbol *LblSym = GetCPISymbol(i);112auto *TS =113static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());114const Constant *C = CPE.Val.ConstVal;115const MCExpr *Value = nullptr;116117Type *Ty = C->getType();118if (const auto *CFP = dyn_cast<ConstantFP>(C)) {119Value = MCConstantExpr::create(120CFP->getValueAPF().bitcastToAPInt().getSExtValue(), OutContext);121} else if (const auto *CI = dyn_cast<ConstantInt>(C)) {122Value = MCConstantExpr::create(CI->getValue().getSExtValue(), OutContext);123} else if (isa<PointerType>(Ty)) {124Value = lowerConstant(C);125} else {126llvm_unreachable("unexpected constant pool entry type");127}128129TS->emitLiteral(LblSym, Value, false);130}131}132133// EmitConstantPool - Print to the current output stream assembly134// representations of the constants in the constant pool MCP. This is135// used to print out constants which have been "spilled to memory" by136// the code generator.137void XtensaAsmPrinter::emitConstantPool() {138const Function &F = MF->getFunction();139const MachineConstantPool *MCP = MF->getConstantPool();140const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();141if (CP.empty())142return;143144OutStreamer->pushSection();145146auto *TS =147static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());148MCSection *CS = getObjFileLowering().SectionForGlobal(&F, TM);149TS->startLiteralSection(CS);150151int CPIdx = 0;152for (const MachineConstantPoolEntry &CPE : CP) {153emitMachineConstantPoolEntry(CPE, CPIdx++);154}155156OutStreamer->popSection();157}158159MCSymbol *160XtensaAsmPrinter::GetConstantPoolIndexSymbol(const MachineOperand &MO) const {161// Create a symbol for the name.162return GetCPISymbol(MO.getIndex());163}164165MCSymbol *XtensaAsmPrinter::GetJumpTableSymbol(const MachineOperand &MO) const {166return GetJTISymbol(MO.getIndex());167}168169MCOperand170XtensaAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,171MachineOperand::MachineOperandType MOTy,172unsigned Offset) const {173const MCSymbol *Symbol;174XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;175176switch (MOTy) {177case MachineOperand::MO_GlobalAddress:178Symbol = getSymbol(MO.getGlobal());179Offset += MO.getOffset();180break;181case MachineOperand::MO_MachineBasicBlock:182Symbol = MO.getMBB()->getSymbol();183break;184case MachineOperand::MO_BlockAddress:185Symbol = GetBlockAddressSymbol(MO.getBlockAddress());186Offset += MO.getOffset();187break;188case MachineOperand::MO_ExternalSymbol:189Symbol = GetExternalSymbolSymbol(MO.getSymbolName());190Offset += MO.getOffset();191break;192case MachineOperand::MO_JumpTableIndex:193Symbol = GetJumpTableSymbol(MO);194break;195case MachineOperand::MO_ConstantPoolIndex:196Symbol = GetConstantPoolIndexSymbol(MO);197Offset += MO.getOffset();198break;199default:200report_fatal_error("<unknown operand type>");201}202203const MCExpr *ME =204MCSymbolRefExpr::create(Symbol, MCSymbolRefExpr::VK_None, OutContext);205ME = XtensaMCExpr::create(ME, Kind, OutContext);206207if (Offset) {208// Assume offset is never negative.209assert(Offset > 0);210211const MCConstantExpr *OffsetExpr =212MCConstantExpr::create(Offset, OutContext);213ME = MCBinaryExpr::createAdd(ME, OffsetExpr, OutContext);214}215216return MCOperand::createExpr(ME);217}218219MCOperand XtensaAsmPrinter::lowerOperand(const MachineOperand &MO,220unsigned Offset) const {221MachineOperand::MachineOperandType MOTy = MO.getType();222223switch (MOTy) {224case MachineOperand::MO_Register:225// Ignore all implicit register operands.226if (MO.isImplicit())227break;228return MCOperand::createReg(MO.getReg());229case MachineOperand::MO_Immediate:230return MCOperand::createImm(MO.getImm() + Offset);231case MachineOperand::MO_RegisterMask:232break;233case MachineOperand::MO_GlobalAddress:234case MachineOperand::MO_MachineBasicBlock:235case MachineOperand::MO_BlockAddress:236case MachineOperand::MO_ExternalSymbol:237case MachineOperand::MO_JumpTableIndex:238case MachineOperand::MO_ConstantPoolIndex:239return LowerSymbolOperand(MO, MOTy, Offset);240default:241report_fatal_error("unknown operand type");242}243244return MCOperand();245}246247void XtensaAsmPrinter::lowerToMCInst(const MachineInstr *MI,248MCInst &OutMI) const {249OutMI.setOpcode(MI->getOpcode());250251for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {252const MachineOperand &MO = MI->getOperand(i);253MCOperand MCOp = lowerOperand(MO);254255if (MCOp.isValid())256OutMI.addOperand(MCOp);257}258}259260extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmPrinter() {261RegisterAsmPrinter<XtensaAsmPrinter> A(getTheXtensaTarget());262}263264265