Skip to content

Commit

Permalink
[M680x0] Base Patch 6: MC and assembly
Browse files Browse the repository at this point in the history
 - MC support for M68k
 - ASM printer
 - Corresponding tests
  • Loading branch information
mshockwave committed Sep 24, 2020
1 parent 253af82 commit d42bc0e
Show file tree
Hide file tree
Showing 33 changed files with 2,780 additions and 0 deletions.
100 changes: 100 additions & 0 deletions llvm/lib/Target/M680x0/M680x0AsmPrinter.cpp
@@ -0,0 +1,100 @@
//===-- M680x0AsmPrinter.cpp - M680x0 LLVM Assembly Printer -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains a printer that converts from our internal representation
/// of machine-dependent LLVM code to GAS-format M680x0 assembly language.
///
//===----------------------------------------------------------------------===//

// TODO #33 make it print Motorola asm

#include "M680x0AsmPrinter.h"

#include "M680x0.h"
#include "M680x0InstrInfo.h"
#include "M680x0MachineFunction.h"

#include "MCTargetDesc/M680x0InstPrinter.h"
#include "MCTargetDesc/M680x0BaseInfo.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include <memory>

using namespace llvm;

#define DEBUG_TYPE "m680x0-asm-printer"

bool M680x0AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
MMFI = MF.getInfo<M680x0MachineFunctionInfo>();
MCInstLowering = std::make_unique<M680x0MCInstLower>(MF, *this);
AsmPrinter::runOnMachineFunction(MF);
return true;
}

void M680x0AsmPrinter::emitInstruction(const MachineInstr *MI) {
switch (MI->getOpcode()) {
default: {
if (MI->isPseudo()) {
LLVM_DEBUG(dbgs() << "Pseudo opcode(" << MI->getOpcode()
<< ") found in EmitInstruction()\n");
llvm_unreachable("Cannot proceed");
}
break;
}
case M680x0::TAILJMPj:
case M680x0::TAILJMPq:
// Lower these as normal, but add some comments.
OutStreamer->AddComment("TAILCALL");
break;
}

MCInst TmpInst0;
MCInstLowering->Lower(MI, TmpInst0);
OutStreamer->emitInstruction(TmpInst0, getSubtargetInfo());
}

void M680x0AsmPrinter::emitFunctionBodyStart() {
// TODO #33
}

void M680x0AsmPrinter::emitFunctionBodyEnd() {
// TODO #33
}

void M680x0AsmPrinter::emitStartOfAsmFile(Module &M) {
OutStreamer->emitSyntaxDirective();
}

void M680x0AsmPrinter::emitEndOfAsmFile(Module &M) {}

extern "C" void LLVMInitializeM680x0AsmPrinter() {
RegisterAsmPrinter<M680x0AsmPrinter> X(TheM680x0Target);
}
63 changes: 63 additions & 0 deletions llvm/lib/Target/M680x0/M680x0AsmPrinter.h
@@ -0,0 +1,63 @@
//===-- M680x0AsmPrinter.h - M680x0 LLVM Assembly Printer -------- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains M680x0 assembler printer declarations.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_M680X0_M680X0ASMPRINTER_H
#define LLVM_LIB_TARGET_M680X0_M680X0ASMPRINTER_H

#include "M680x0MCInstLower.h"
#include "M680x0TargetMachine.h"

#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Target/TargetMachine.h"

namespace llvm {
class MCStreamer;
class MachineInstr;
class MachineBasicBlock;
class Module;
class raw_ostream;

class M680x0Subtarget;
class M680x0MachineFunctionInfo;

class LLVM_LIBRARY_VISIBILITY M680x0AsmPrinter : public AsmPrinter {

void EmitInstrWithMacroNoAT(const MachineInstr *MI);

public:
const M680x0Subtarget *Subtarget;
const M680x0MachineFunctionInfo *MMFI;
std::unique_ptr<M680x0MCInstLower> MCInstLowering;

explicit M680x0AsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)) {
Subtarget = static_cast<M680x0TargetMachine &>(TM).getSubtargetImpl();
}

StringRef getPassName() const override { return "M680x0 Assembly Printer"; }

virtual bool runOnMachineFunction(MachineFunction &MF) override;

void emitInstruction(const MachineInstr *MI) override;
void emitFunctionBodyStart() override;
void emitFunctionBodyEnd() override;
void emitStartOfAsmFile(Module &M) override;
void emitEndOfAsmFile(Module &M) override;
};
} // namespace llvm

#endif
182 changes: 182 additions & 0 deletions llvm/lib/Target/M680x0/M680x0MCInstLower.cpp
@@ -0,0 +1,182 @@
//===-- M680x0MCInstLower.cpp - M680x0 MachineInstr to MCInst ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains code to lower M680x0 MachineInstrs to their
/// corresponding MCInst records.
///
//===----------------------------------------------------------------------===//

#include "M680x0MCInstLower.h"

#include "M680x0AsmPrinter.h"
#include "M680x0InstrInfo.h"

#include "MCTargetDesc/M680x0BaseInfo.h"

#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"

using namespace llvm;

#define DEBUG_TYPE "m68k-mc-inst-lower"

M680x0MCInstLower::M680x0MCInstLower(MachineFunction &MF, M680x0AsmPrinter &AP)
: Ctx(MF.getContext()), MF(MF), TM(MF.getTarget()), MAI(*TM.getMCAsmInfo()),
AsmPrinter(AP) {}

MCSymbol *
M680x0MCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {
assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&
"Isn't a symbol reference");

const auto& TT = TM.getTargetTriple();
if (MO.isGlobal() && TT.isOSBinFormatELF())
return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());

const DataLayout &DL = MF.getDataLayout();

MCSymbol *Sym = nullptr;
SmallString<128> Name;
StringRef Suffix;

if (!Suffix.empty())
Name += DL.getPrivateGlobalPrefix();

if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
AsmPrinter.getNameWithPrefix(Name, GV);
} else if (MO.isSymbol()) {
Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);
} else if (MO.isMBB()) {
assert(Suffix.empty());
Sym = MO.getMBB()->getSymbol();
}

Name += Suffix;
if (!Sym)
Sym = Ctx.getOrCreateSymbol(Name);

return Sym;
}

MCOperand M680x0MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const {
// FIXME We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing. This fixme is originally from X86
const MCExpr *Expr = nullptr;
MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;

switch (MO.getTargetFlags()) {
default:
llvm_unreachable("Unknown target flag on GV operand");
case M680x0II::MO_NO_FLAG:
case M680x0II::MO_ABSOLUTE_ADDRESS:
case M680x0II::MO_PC_RELATIVE_ADDRESS:
break;
case M680x0II::MO_GOTPCREL:
RefKind = MCSymbolRefExpr::VK_GOTPCREL;
break;
case M680x0II::MO_GOT:
RefKind = MCSymbolRefExpr::VK_GOT;
break;
case M680x0II::MO_GOTOFF:
RefKind = MCSymbolRefExpr::VK_GOTOFF;
break;
case M680x0II::MO_PLT:
RefKind = MCSymbolRefExpr::VK_PLT;
break;
}

if (!Expr) {
Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
}

if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) {
Expr = MCBinaryExpr::createAdd(
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
}

return MCOperand::createExpr(Expr);
}

Optional<MCOperand>
M680x0MCInstLower::LowerOperand(const MachineInstr *MI,
const MachineOperand &MO) const {
switch (MO.getType()) {
default:
LLVM_DEBUG(MI->dump());
llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit())
return None;
return MCOperand::createReg(MO.getReg());
case MachineOperand::MO_Immediate:
return MCOperand::createImm(MO.getImm());
case MachineOperand::MO_MachineBasicBlock:
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
case MachineOperand::MO_MCSymbol:
return LowerSymbolOperand(MO, MO.getMCSymbol());
case MachineOperand::MO_JumpTableIndex:
return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
case MachineOperand::MO_ConstantPoolIndex:
return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
case MachineOperand::MO_BlockAddress:
return LowerSymbolOperand(
MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
case MachineOperand::MO_RegisterMask:
// Ignore call clobbers.
return None;
}
}

void M680x0MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
OutMI.setOpcode(MI->getOpcode());

for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
Optional<MCOperand> MCOp = LowerOperand(MI, MO);

if (MCOp.hasValue() && MCOp.getValue().isValid())
OutMI.addOperand(MCOp.getValue());
}

switch (OutMI.getOpcode()) {

// TAILJMPj, TAILJMPq - Lower to the correct jump instructions.
case M680x0::TAILJMPj:
case M680x0::TAILJMPq: {
unsigned Opcode;
switch (OutMI.getOpcode()) {
default:
llvm_unreachable("Invalid opcode");
case M680x0::TAILJMPj:
Opcode = M680x0::JMP32j;
break;
case M680x0::TAILJMPq:
Opcode = M680x0::BRA8;
break;
}

MCOperand Saved = OutMI.getOperand(0);
OutMI = MCInst();
OutMI.setOpcode(Opcode);
OutMI.addOperand(Saved);
break;
}
}
}

0 comments on commit d42bc0e

Please sign in to comment.