mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-16 11:30:51 +00:00
974a445bd9
subsequent changes are easier to review. About to fix some layering issues, and wanted to separate out the necessary churn. Also comment and sink the include of "Windows.h" in three .inc files to match the usage in Memory.inc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198685 91177308-0d34-0410-b5e6-96231b3b80d8
204 lines
6.5 KiB
C++
204 lines
6.5 KiB
C++
//===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This class prints an Hexagon MCInst to a .s file.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "asm-printer"
|
|
#include "HexagonAsmPrinter.h"
|
|
#include "Hexagon.h"
|
|
#include "HexagonInstPrinter.h"
|
|
#include "MCTargetDesc/HexagonMCInst.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/MC/MCAsmInfo.h"
|
|
#include "llvm/MC/MCExpr.h"
|
|
#include "llvm/MC/MCInst.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace llvm;
|
|
|
|
#define GET_INSTRUCTION_NAME
|
|
#include "HexagonGenAsmWriter.inc"
|
|
|
|
const char HexagonInstPrinter::PacketPadding = '\t';
|
|
|
|
StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
|
|
return MII.getName(Opcode);
|
|
}
|
|
|
|
StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
|
|
return getRegisterName(RegNo);
|
|
}
|
|
|
|
void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
|
StringRef Annot) {
|
|
printInst((const HexagonMCInst*)(MI), O, Annot);
|
|
}
|
|
|
|
void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
|
|
StringRef Annot) {
|
|
const char startPacket = '{',
|
|
endPacket = '}';
|
|
// TODO: add outer HW loop when it's supported too.
|
|
if (MI->getOpcode() == Hexagon::ENDLOOP0) {
|
|
// Ending a harware loop is different from ending an regular packet.
|
|
assert(MI->isPacketEnd() && "Loop-end must also end the packet");
|
|
|
|
if (MI->isPacketStart()) {
|
|
// There must be a packet to end a loop.
|
|
// FIXME: when shuffling is always run, this shouldn't be needed.
|
|
HexagonMCInst Nop;
|
|
StringRef NoAnnot;
|
|
|
|
Nop.setOpcode (Hexagon::NOP);
|
|
Nop.setPacketStart (MI->isPacketStart());
|
|
printInst (&Nop, O, NoAnnot);
|
|
}
|
|
|
|
// Close the packet.
|
|
if (MI->isPacketEnd())
|
|
O << PacketPadding << endPacket;
|
|
|
|
printInstruction(MI, O);
|
|
}
|
|
else {
|
|
// Prefix the insn opening the packet.
|
|
if (MI->isPacketStart())
|
|
O << PacketPadding << startPacket << '\n';
|
|
|
|
printInstruction(MI, O);
|
|
|
|
// Suffix the insn closing the packet.
|
|
if (MI->isPacketEnd())
|
|
// Suffix the packet in a new line always, since the GNU assembler has
|
|
// issues with a closing brace on the same line as CONST{32,64}.
|
|
O << '\n' << PacketPadding << endPacket;
|
|
}
|
|
|
|
printAnnotation(O, Annot);
|
|
}
|
|
|
|
void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
const MCOperand& MO = MI->getOperand(OpNo);
|
|
|
|
if (MO.isReg()) {
|
|
O << getRegisterName(MO.getReg());
|
|
} else if(MO.isExpr()) {
|
|
O << *MO.getExpr();
|
|
} else if(MO.isImm()) {
|
|
printImmOperand(MI, OpNo, O);
|
|
} else {
|
|
llvm_unreachable("Unknown operand");
|
|
}
|
|
}
|
|
|
|
void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
const MCOperand& MO = MI->getOperand(OpNo);
|
|
|
|
if(MO.isExpr()) {
|
|
O << *MO.getExpr();
|
|
} else if(MO.isImm()) {
|
|
O << MI->getOperand(OpNo).getImm();
|
|
} else {
|
|
llvm_unreachable("Unknown operand");
|
|
}
|
|
}
|
|
|
|
void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
const HexagonMCInst *HMCI = static_cast<const HexagonMCInst*>(MI);
|
|
if (HMCI->isConstExtended())
|
|
O << "#";
|
|
printOperand(MI, OpNo, O);
|
|
}
|
|
|
|
void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
|
|
unsigned OpNo, raw_ostream &O) const {
|
|
O << MI->getOperand(OpNo).getImm();
|
|
}
|
|
|
|
void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
O << -MI->getOperand(OpNo).getImm();
|
|
}
|
|
|
|
void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
O << -1;
|
|
}
|
|
|
|
void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
const MCOperand& MO0 = MI->getOperand(OpNo);
|
|
const MCOperand& MO1 = MI->getOperand(OpNo + 1);
|
|
|
|
O << getRegisterName(MO0.getReg());
|
|
O << " + #" << MO1.getImm();
|
|
}
|
|
|
|
void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
const MCOperand& MO0 = MI->getOperand(OpNo);
|
|
const MCOperand& MO1 = MI->getOperand(OpNo + 1);
|
|
|
|
O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm();
|
|
}
|
|
|
|
void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
|
|
|
|
printOperand(MI, OpNo, O);
|
|
}
|
|
|
|
void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
|
|
|
|
printOperand(MI, OpNo, O);
|
|
}
|
|
|
|
void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
|
|
|
|
printOperand(MI, OpNo, O);
|
|
}
|
|
|
|
void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
// Branches can take an immediate operand. This is used by the branch
|
|
// selection pass to print $+8, an eight byte displacement from the PC.
|
|
llvm_unreachable("Unknown branch operand.");
|
|
}
|
|
|
|
void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
}
|
|
|
|
void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
}
|
|
|
|
void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O) const {
|
|
}
|
|
|
|
void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
|
|
raw_ostream &O, bool hi) const {
|
|
assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
|
|
|
|
O << '#' << (hi ? "HI" : "LO") << "(#";
|
|
printOperand(MI, OpNo, O);
|
|
O << ')';
|
|
}
|