brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.4 KiB · 4d07400 Raw
322 lines · cpp
1//===- XtensaAsmPrinter.cpp Xtensa LLVM Assembly Printer ------------------===//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 a printer that converts from our internal representation10// of machine-dependent LLVM code to GAS-format Xtensa assembly language.11//12//===----------------------------------------------------------------------===//13 14#include "XtensaAsmPrinter.h"15#include "MCTargetDesc/XtensaInstPrinter.h"16#include "MCTargetDesc/XtensaMCAsmInfo.h"17#include "MCTargetDesc/XtensaTargetStreamer.h"18#include "TargetInfo/XtensaTargetInfo.h"19#include "XtensaConstantPoolValue.h"20#include "llvm/ADT/StringExtras.h"21#include "llvm/BinaryFormat/ELF.h"22#include "llvm/CodeGen/MachineConstantPool.h"23#include "llvm/CodeGen/MachineModuleInfoImpls.h"24#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"25#include "llvm/MC/MCExpr.h"26#include "llvm/MC/MCInstBuilder.h"27#include "llvm/MC/MCSectionELF.h"28#include "llvm/MC/MCStreamer.h"29#include "llvm/MC/MCSymbol.h"30#include "llvm/MC/MCSymbolELF.h"31#include "llvm/MC/TargetRegistry.h"32 33using namespace llvm;34 35static Xtensa::Specifier36getModifierSpecifier(XtensaCP::XtensaCPModifier Modifier) {37  switch (Modifier) {38  case XtensaCP::no_modifier:39    return Xtensa::S_None;40  case XtensaCP::TPOFF:41    return Xtensa::S_TPOFF;42  }43  report_fatal_error("Invalid XtensaCPModifier!");44}45 46void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {47  unsigned Opc = MI->getOpcode();48 49  switch (Opc) {50  case Xtensa::BR_JT:51    EmitToStreamer(52        *OutStreamer,53        MCInstBuilder(Xtensa::JX).addReg(MI->getOperand(0).getReg()));54    return;55  default:56    MCInst LoweredMI;57    lowerToMCInst(MI, LoweredMI);58    EmitToStreamer(*OutStreamer, LoweredMI);59    return;60  }61}62 63void XtensaAsmPrinter::emitMachineConstantPoolValue(64    MachineConstantPoolValue *MCPV) {65  XtensaConstantPoolValue *XtensaCPV =66      static_cast<XtensaConstantPoolValue *>(MCPV);67  MCSymbol *MCSym;68 69  if (XtensaCPV->isBlockAddress()) {70    const BlockAddress *BA =71        cast<XtensaConstantPoolConstant>(XtensaCPV)->getBlockAddress();72    MCSym = GetBlockAddressSymbol(BA);73  } else if (XtensaCPV->isMachineBasicBlock()) {74    const MachineBasicBlock *MBB =75        cast<XtensaConstantPoolMBB>(XtensaCPV)->getMBB();76    MCSym = MBB->getSymbol();77  } else if (XtensaCPV->isJumpTable()) {78    unsigned Idx = cast<XtensaConstantPoolJumpTable>(XtensaCPV)->getIndex();79    MCSym = this->GetJTISymbol(Idx, false);80  } else {81    assert(XtensaCPV->isExtSymbol() && "unrecognized constant pool value");82    XtensaConstantPoolSymbol *XtensaSym =83        cast<XtensaConstantPoolSymbol>(XtensaCPV);84    const char *SymName = XtensaSym->getSymbol();85 86    if (XtensaSym->isPrivateLinkage()) {87      const DataLayout &DL = getDataLayout();88      MCSym = OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +89                                           SymName);90    } else {91      MCSym = OutContext.getOrCreateSymbol(SymName);92    }93  }94 95  MCSymbol *LblSym = GetCPISymbol(XtensaCPV->getLabelId());96  auto *TS =97      static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());98  auto Spec = getModifierSpecifier(XtensaCPV->getModifier());99 100  if (XtensaCPV->getModifier() != XtensaCP::no_modifier) {101    std::string SymName(MCSym->getName());102    StringRef Modifier = XtensaCPV->getModifierText();103    SymName += Modifier;104    MCSym = OutContext.getOrCreateSymbol(SymName);105  }106 107  const MCExpr *Expr = MCSymbolRefExpr::create(MCSym, Spec, OutContext);108  TS->emitLiteral(LblSym, Expr, false);109}110 111void XtensaAsmPrinter::emitMachineConstantPoolEntry(112    const MachineConstantPoolEntry &CPE, int i) {113  if (CPE.isMachineConstantPoolEntry()) {114    XtensaConstantPoolValue *XtensaCPV =115        static_cast<XtensaConstantPoolValue *>(CPE.Val.MachineCPVal);116    XtensaCPV->setLabelId(i);117    emitMachineConstantPoolValue(CPE.Val.MachineCPVal);118  } else {119    MCSymbol *LblSym = GetCPISymbol(i);120    auto *TS =121        static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());122    const Constant *C = CPE.Val.ConstVal;123    const MCExpr *Value = nullptr;124 125    Type *Ty = C->getType();126    if (const auto *CFP = dyn_cast<ConstantFP>(C)) {127      Value = MCConstantExpr::create(128          CFP->getValueAPF().bitcastToAPInt().getSExtValue(), OutContext);129    } else if (const auto *CI = dyn_cast<ConstantInt>(C)) {130      Value = MCConstantExpr::create(CI->getValue().getSExtValue(), OutContext);131    } else if (isa<PointerType>(Ty)) {132      Value = lowerConstant(C);133    } else {134      llvm_unreachable("unexpected constant pool entry type");135    }136 137    TS->emitLiteral(LblSym, Value, false);138  }139}140 141// EmitConstantPool - Print to the current output stream assembly142// representations of the constants in the constant pool MCP. This is143// used to print out constants which have been "spilled to memory" by144// the code generator.145void XtensaAsmPrinter::emitConstantPool() {146  const Function &F = MF->getFunction();147  const MachineConstantPool *MCP = MF->getConstantPool();148  const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();149  if (CP.empty())150    return;151 152  OutStreamer->pushSection();153 154  auto *TS =155      static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());156  MCSection *CS = getObjFileLowering().SectionForGlobal(&F, TM);157  TS->startLiteralSection(CS);158 159  int CPIdx = 0;160  for (const MachineConstantPoolEntry &CPE : CP) {161    emitMachineConstantPoolEntry(CPE, CPIdx++);162  }163 164  OutStreamer->popSection();165}166 167void XtensaAsmPrinter::printOperand(const MachineInstr *MI, int OpNo,168                                    raw_ostream &O) {169  const MachineOperand &MO = MI->getOperand(OpNo);170 171  switch (MO.getType()) {172  case MachineOperand::MO_Register:173  case MachineOperand::MO_Immediate: {174    MCOperand MC = lowerOperand(MI->getOperand(OpNo));175    XtensaInstPrinter::printOperand(MC, O);176    break;177  }178  default:179    llvm_unreachable("unknown operand type");180  }181}182 183bool XtensaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,184                                       const char *ExtraCode, raw_ostream &O) {185  // Print the operand if there is no operand modifier.186  if (!ExtraCode || !ExtraCode[0]) {187    printOperand(MI, OpNo, O);188    return false;189  }190 191  // Fallback to the default implementation.192  return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);193}194 195bool XtensaAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,196                                             unsigned OpNo,197                                             const char *ExtraCode,198                                             raw_ostream &OS) {199  if (ExtraCode && ExtraCode[0])200    return true; // Unknown modifier.201 202  assert(OpNo + 1 < MI->getNumOperands() && "Insufficient operands");203 204  const MachineOperand &Base = MI->getOperand(OpNo);205  const MachineOperand &Offset = MI->getOperand(OpNo + 1);206 207  assert(Base.isReg() &&208         "Unexpected base pointer for inline asm memory operand.");209  assert(Offset.isImm() && "Unexpected offset for inline asm memory operand.");210 211  OS << XtensaInstPrinter::getRegisterName(Base.getReg());212  OS << ", ";213  OS << Offset.getImm();214 215  return false;216}217 218MCSymbol *219XtensaAsmPrinter::GetConstantPoolIndexSymbol(const MachineOperand &MO) const {220  // Create a symbol for the name.221  return GetCPISymbol(MO.getIndex());222}223 224MCSymbol *XtensaAsmPrinter::GetJumpTableSymbol(const MachineOperand &MO) const {225  return GetJTISymbol(MO.getIndex());226}227 228MCOperand229XtensaAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,230                                     MachineOperand::MachineOperandType MOTy,231                                     unsigned Offset) const {232  const MCSymbol *Symbol;233  switch (MOTy) {234  case MachineOperand::MO_GlobalAddress:235    Symbol = getSymbol(MO.getGlobal());236    Offset += MO.getOffset();237    break;238  case MachineOperand::MO_MachineBasicBlock:239    Symbol = MO.getMBB()->getSymbol();240    break;241  case MachineOperand::MO_BlockAddress:242    Symbol = GetBlockAddressSymbol(MO.getBlockAddress());243    Offset += MO.getOffset();244    break;245  case MachineOperand::MO_ExternalSymbol:246    Symbol = GetExternalSymbolSymbol(MO.getSymbolName());247    Offset += MO.getOffset();248    break;249  case MachineOperand::MO_JumpTableIndex:250    Symbol = GetJumpTableSymbol(MO);251    break;252  case MachineOperand::MO_ConstantPoolIndex:253    Symbol = GetConstantPoolIndexSymbol(MO);254    Offset += MO.getOffset();255    break;256  default:257    report_fatal_error("<unknown operand type>");258  }259 260  const MCExpr *ME = MCSymbolRefExpr::create(Symbol, OutContext);261  if (Offset) {262    // Assume offset is never negative.263    assert(Offset > 0);264 265    const MCConstantExpr *OffsetExpr =266        MCConstantExpr::create(Offset, OutContext);267    ME = MCBinaryExpr::createAdd(ME, OffsetExpr, OutContext);268  }269 270  return MCOperand::createExpr(ME);271}272 273MCOperand XtensaAsmPrinter::lowerOperand(const MachineOperand &MO,274                                         unsigned Offset) const {275  MachineOperand::MachineOperandType MOTy = MO.getType();276 277  switch (MOTy) {278  case MachineOperand::MO_Register:279    // Ignore all implicit register operands.280    if (MO.isImplicit())281      break;282    return MCOperand::createReg(MO.getReg());283  case MachineOperand::MO_Immediate:284    return MCOperand::createImm(MO.getImm() + Offset);285  case MachineOperand::MO_RegisterMask:286    break;287  case MachineOperand::MO_GlobalAddress:288  case MachineOperand::MO_MachineBasicBlock:289  case MachineOperand::MO_BlockAddress:290  case MachineOperand::MO_ExternalSymbol:291  case MachineOperand::MO_JumpTableIndex:292  case MachineOperand::MO_ConstantPoolIndex:293    return LowerSymbolOperand(MO, MOTy, Offset);294  default:295    report_fatal_error("unknown operand type");296  }297 298  return MCOperand();299}300 301void XtensaAsmPrinter::lowerToMCInst(const MachineInstr *MI,302                                     MCInst &OutMI) const {303  OutMI.setOpcode(MI->getOpcode());304 305  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {306    const MachineOperand &MO = MI->getOperand(i);307    MCOperand MCOp = lowerOperand(MO);308 309    if (MCOp.isValid())310      OutMI.addOperand(MCOp);311  }312}313 314char XtensaAsmPrinter::ID = 0;315 316INITIALIZE_PASS(XtensaAsmPrinter, "xtensa-asm-printer",317                "Xtensa Assembly Printer", false, false)318 319extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmPrinter() {320  RegisterAsmPrinter<XtensaAsmPrinter> A(getTheXtensaTarget());321}322