brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 0437400 Raw
206 lines · cpp
1//===-- M68kAsmPrinter.cpp - M68k LLVM Assembly Printer ---------*- C++ -*-===//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/// \file10/// This file contains a printer that converts from our internal representation11/// of machine-dependent LLVM code to GAS-format M68k assembly language.12///13//===----------------------------------------------------------------------===//14 15// TODO Conform to Motorola ASM syntax16 17#include "M68kAsmPrinter.h"18 19#include "M68k.h"20#include "M68kMachineFunction.h"21#include "MCTargetDesc/M68kInstPrinter.h"22#include "TargetInfo/M68kTargetInfo.h"23 24#include "llvm/MC/TargetRegistry.h"25 26using namespace llvm;27 28#define DEBUG_TYPE "m68k-asm-printer"29 30bool M68kAsmPrinter::runOnMachineFunction(MachineFunction &MF) {31  MMFI = MF.getInfo<M68kMachineFunctionInfo>();32  MCInstLowering = std::make_unique<M68kMCInstLower>(MF, *this);33  AsmPrinter::runOnMachineFunction(MF);34  return true;35}36 37void M68kAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,38                                  raw_ostream &OS) {39  const MachineOperand &MO = MI->getOperand(OpNum);40  switch (MO.getType()) {41  case MachineOperand::MO_Register:42    OS << "%" << M68kInstPrinter::getRegisterName(MO.getReg());43    break;44  case MachineOperand::MO_Immediate:45    OS << '#' << MO.getImm();46    break;47  case MachineOperand::MO_MachineBasicBlock:48    MO.getMBB()->getSymbol()->print(OS, MAI);49    break;50  case MachineOperand::MO_GlobalAddress:51    PrintSymbolOperand(MO, OS);52    break;53  case MachineOperand::MO_BlockAddress:54    GetBlockAddressSymbol(MO.getBlockAddress())->print(OS, MAI);55    break;56  case MachineOperand::MO_ConstantPoolIndex: {57    const DataLayout &DL = getDataLayout();58    OS << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'59       << MO.getIndex();60    break;61  }62  default:63    llvm_unreachable("not implemented");64  }65}66 67bool M68kAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,68                                     const char *ExtraCode, raw_ostream &OS) {69  // Print the operand if there is no operand modifier.70  if (!ExtraCode || !ExtraCode[0]) {71    printOperand(MI, OpNo, OS);72    return false;73  }74 75  // Fallback to the default implementation.76  return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);77}78 79void M68kAsmPrinter::printDisp(const MachineInstr *MI, unsigned opNum,80                               raw_ostream &O) {81  // Print immediate displacement without the '#' predix82  const MachineOperand &Op = MI->getOperand(opNum);83  if (Op.isImm()) {84    O << Op.getImm();85    return;86  }87  // Displacement is relocatable, so we're pretty permissive about what88  // can be put here.89  printOperand(MI, opNum, O);90}91 92void M68kAsmPrinter::printAbsMem(const MachineInstr *MI, unsigned OpNum,93                                 raw_ostream &O) {94  const MachineOperand &MO = MI->getOperand(OpNum);95  if (MO.isImm())96    O << format("$%0" PRIx64, (uint64_t)MO.getImm());97  else98    PrintAsmMemoryOperand(MI, OpNum, nullptr, O);99}100 101bool M68kAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,102                                           unsigned OpNo, const char *ExtraCode,103                                           raw_ostream &OS) {104  const MachineOperand &MO = MI->getOperand(OpNo);105  switch (MO.getType()) {106  case MachineOperand::MO_Immediate:107    // Immediate value that goes here is the addressing mode kind we set108    // in M68kDAGToDAGISel::SelectInlineAsmMemoryOperand.109    using namespace M68k;110    // Skip the addressing mode kind operand.111    ++OpNo;112    // Decode MemAddrModeKind.113    switch (static_cast<MemAddrModeKind>(MO.getImm())) {114    case MemAddrModeKind::j:115      printARIMem(MI, OpNo, OS);116      break;117    case MemAddrModeKind::o:118      printARIPIMem(MI, OpNo, OS);119      break;120    case MemAddrModeKind::e:121      printARIPDMem(MI, OpNo, OS);122      break;123    case MemAddrModeKind::p:124      printARIDMem(MI, OpNo, OS);125      break;126    case MemAddrModeKind::f:127    case MemAddrModeKind::F:128      printARIIMem(MI, OpNo, OS);129      break;130    case MemAddrModeKind::k:131      printPCIMem(MI, 0, OpNo, OS);132      break;133    case MemAddrModeKind::q:134      printPCDMem(MI, 0, OpNo, OS);135      break;136    case MemAddrModeKind::b:137      printAbsMem(MI, OpNo, OS);138      break;139    default:140      llvm_unreachable("Unrecognized memory addressing mode");141    }142    return false;143  case MachineOperand::MO_GlobalAddress:144    PrintSymbolOperand(MO, OS);145    return false;146  case MachineOperand::MO_BlockAddress:147    GetBlockAddressSymbol(MO.getBlockAddress())->print(OS, MAI);148    return false;149  case MachineOperand::MO_Register:150    // This is a special case where it is treated as a memory reference, with151    // the register holding the address value. Thus, we print it as ARI here.152    if (M68kII::isAddressRegister(MO.getReg())) {153      printARIMem(MI, OpNo, OS);154      return false;155    }156    break;157  default:158    break;159  }160  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);161}162 163void M68kAsmPrinter::emitInstruction(const MachineInstr *MI) {164  M68k_MC::verifyInstructionPredicates(MI->getOpcode(),165                                       getSubtargetInfo().getFeatureBits());166 167  switch (MI->getOpcode()) {168  default: {169    if (MI->isPseudo()) {170      LLVM_DEBUG(dbgs() << "Pseudo opcode(" << MI->getOpcode()171                        << ") found in EmitInstruction()\n");172      llvm_unreachable("Cannot proceed");173    }174    break;175  }176  case M68k::TAILJMPj:177  case M68k::TAILJMPq:178    // Lower these as normal, but add some comments.179    OutStreamer->AddComment("TAILCALL");180    break;181  }182 183  MCInst TmpInst0;184  MCInstLowering->Lower(MI, TmpInst0);185  OutStreamer->emitInstruction(TmpInst0, getSubtargetInfo());186}187 188void M68kAsmPrinter::emitFunctionBodyStart() {}189 190void M68kAsmPrinter::emitFunctionBodyEnd() {}191 192void M68kAsmPrinter::emitStartOfAsmFile(Module &M) {193  OutStreamer->emitSyntaxDirective();194}195 196void M68kAsmPrinter::emitEndOfAsmFile(Module &M) {}197 198char M68kAsmPrinter::ID = 0;199 200INITIALIZE_PASS(M68kAsmPrinter, "m68k-asm-printer", "M68k Assembly Printer",201                false, false)202 203extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kAsmPrinter() {204  RegisterAsmPrinter<M68kAsmPrinter> X(getTheM68kTarget());205}206