1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 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());
}
|