diff options
Diffstat (limited to 'lib/Target/Nios2/Nios2AsmPrinter.cpp')
| -rw-r--r-- | lib/Target/Nios2/Nios2AsmPrinter.cpp | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/lib/Target/Nios2/Nios2AsmPrinter.cpp b/lib/Target/Nios2/Nios2AsmPrinter.cpp new file mode 100644 index 000000000000..1abf19591774 --- /dev/null +++ b/lib/Target/Nios2/Nios2AsmPrinter.cpp @@ -0,0 +1,153 @@ +//===-- Nios2AsmPrinter.cpp - Nios2 LLVM Assembly Printer -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to GAS-format NIOS2 assembly language. +// +//===----------------------------------------------------------------------===// + +#include "InstPrinter/Nios2InstPrinter.h" +#include "MCTargetDesc/Nios2BaseInfo.h" +#include "Nios2.h" +#include "Nios2TargetMachine.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +#define DEBUG_TYPE "nios2-asm-printer" + +namespace { + +class Nios2AsmPrinter : public AsmPrinter { + +public: + explicit Nios2AsmPrinter(TargetMachine &TM, + std::unique_ptr<MCStreamer> Streamer) + : AsmPrinter(TM, std::move(Streamer)) {} + + StringRef getPassName() const override { return "Nios2 Assembly Printer"; } + + //- EmitInstruction() must exists or will have run time error. + void EmitInstruction(const MachineInstr *MI) override; + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O) override; + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O) override; + void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); + void EmitFunctionEntryLabel() override; +}; +} // namespace + +//- EmitInstruction() must exists or will have run time error. +void Nios2AsmPrinter::EmitInstruction(const MachineInstr *MI) { + + // Print out both ordinary instruction and boudle instruction + MachineBasicBlock::const_instr_iterator I = MI->getIterator(); + MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); + + do { + + if (I->isPseudo()) { + llvm_unreachable("Pseudo opcode found in EmitInstruction()"); + } + + MCInst TmpInst0; + LowerNios2MachineInstToMCInst(&*I, TmpInst0, *this); + EmitToStreamer(*OutStreamer, TmpInst0); + } while ((++I != E) && I->isInsideBundle()); // Delay slot check +} + +// .type main,@function +//-> .ent main # @main +// main: +void Nios2AsmPrinter::EmitFunctionEntryLabel() { + OutStreamer->EmitLabel(CurrentFnSym); +} + +// Print out an operand for an inline asm expression. +bool Nios2AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, + unsigned AsmVariant, + const char *ExtraCode, raw_ostream &O) { + printOperand(MI, OpNum, O); + return false; +} + +bool Nios2AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNum, unsigned AsmVariant, + const char *ExtraCode, + raw_ostream &O) { + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier + + const MachineOperand &MO = MI->getOperand(OpNum); + assert(MO.isReg() && "unexpected inline asm memory operand"); + O << "($" << Nios2InstPrinter::getRegisterName(MO.getReg()) << ")"; + + return false; +} + +void Nios2AsmPrinter::printOperand(const MachineInstr *MI, int opNum, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(opNum); + bool closeP = false; + + if (MO.getTargetFlags()) + closeP = true; + + switch (MO.getTargetFlags()) { + case Nios2FG::MO_ABS_HI: + O << "%hiadj("; + break; + case Nios2FG::MO_ABS_LO: + O << "%lo("; + break; + } + + switch (MO.getType()) { + case MachineOperand::MO_Register: + O << '$' + << StringRef(Nios2InstPrinter::getRegisterName(MO.getReg())).lower(); + break; + + case MachineOperand::MO_Immediate: + O << MO.getImm(); + break; + + case MachineOperand::MO_MachineBasicBlock: + MO.getMBB()->getSymbol()->print(O, MAI); + return; + + case MachineOperand::MO_GlobalAddress: + getSymbol(MO.getGlobal())->print(O, MAI); + break; + + case MachineOperand::MO_BlockAddress: + O << GetBlockAddressSymbol(MO.getBlockAddress())->getName(); + break; + + case MachineOperand::MO_ExternalSymbol: + O << MO.getSymbolName(); + break; + + default: + llvm_unreachable("<unknown operand type>"); + } + + if (closeP) + O << ")"; +} + +// Force static initialization. +extern "C" void LLVMInitializeNios2AsmPrinter() { + RegisterAsmPrinter<Nios2AsmPrinter> X(getTheNios2Target()); +} |
