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