Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[M680x0] Base Patch 6: MC and assembly
- MC support for M68k - ASM printer - Corresponding tests
- Loading branch information
1 parent
253af82
commit d42bc0e
Showing
33 changed files
with
2,780 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} | ||
} |
Oops, something went wrong.