HexagonInstPrinter.cpp revision 263508
1//===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This class prints an Hexagon MCInst to a .s file. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "asm-printer" 15#include "HexagonAsmPrinter.h" 16#include "Hexagon.h" 17#include "HexagonInstPrinter.h" 18#include "MCTargetDesc/HexagonMCInst.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/ADT/StringExtras.h" 21#include "llvm/MC/MCAsmInfo.h" 22#include "llvm/MC/MCExpr.h" 23#include "llvm/Support/raw_ostream.h" 24 25using namespace llvm; 26 27#define GET_INSTRUCTION_NAME 28#include "HexagonGenAsmWriter.inc" 29 30const char HexagonInstPrinter::PacketPadding = '\t'; 31 32StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { 33 return MII.getName(Opcode); 34} 35 36StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { 37 return getRegisterName(RegNo); 38} 39 40void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 41 StringRef Annot) { 42 printInst((const HexagonMCInst*)(MI), O, Annot); 43} 44 45void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O, 46 StringRef Annot) { 47 const char startPacket = '{', 48 endPacket = '}'; 49 // TODO: add outer HW loop when it's supported too. 50 if (MI->getOpcode() == Hexagon::ENDLOOP0) { 51 // Ending a harware loop is different from ending an regular packet. 52 assert(MI->isPacketEnd() && "Loop-end must also end the packet"); 53 54 if (MI->isPacketStart()) { 55 // There must be a packet to end a loop. 56 // FIXME: when shuffling is always run, this shouldn't be needed. 57 HexagonMCInst Nop; 58 StringRef NoAnnot; 59 60 Nop.setOpcode (Hexagon::NOP); 61 Nop.setPacketStart (MI->isPacketStart()); 62 printInst (&Nop, O, NoAnnot); 63 } 64 65 // Close the packet. 66 if (MI->isPacketEnd()) 67 O << PacketPadding << endPacket; 68 69 printInstruction(MI, O); 70 } 71 else { 72 // Prefix the insn opening the packet. 73 if (MI->isPacketStart()) 74 O << PacketPadding << startPacket << '\n'; 75 76 printInstruction(MI, O); 77 78 // Suffix the insn closing the packet. 79 if (MI->isPacketEnd()) 80 // Suffix the packet in a new line always, since the GNU assembler has 81 // issues with a closing brace on the same line as CONST{32,64}. 82 O << '\n' << PacketPadding << endPacket; 83 } 84 85 printAnnotation(O, Annot); 86} 87 88void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 89 raw_ostream &O) const { 90 const MCOperand& MO = MI->getOperand(OpNo); 91 92 if (MO.isReg()) { 93 O << getRegisterName(MO.getReg()); 94 } else if(MO.isExpr()) { 95 O << *MO.getExpr(); 96 } else if(MO.isImm()) { 97 printImmOperand(MI, OpNo, O); 98 } else { 99 llvm_unreachable("Unknown operand"); 100 } 101} 102 103void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo, 104 raw_ostream &O) const { 105 const MCOperand& MO = MI->getOperand(OpNo); 106 107 if(MO.isExpr()) { 108 O << *MO.getExpr(); 109 } else if(MO.isImm()) { 110 O << MI->getOperand(OpNo).getImm(); 111 } else { 112 llvm_unreachable("Unknown operand"); 113 } 114} 115 116void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo, 117 raw_ostream &O) const { 118 const HexagonMCInst *HMCI = static_cast<const HexagonMCInst*>(MI); 119 if (HMCI->isConstExtended()) 120 O << "#"; 121 printOperand(MI, OpNo, O); 122} 123 124void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, 125 unsigned OpNo, raw_ostream &O) const { 126 O << MI->getOperand(OpNo).getImm(); 127} 128 129void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo, 130 raw_ostream &O) const { 131 O << -MI->getOperand(OpNo).getImm(); 132} 133 134void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo, 135 raw_ostream &O) const { 136 O << -1; 137} 138 139void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo, 140 raw_ostream &O) const { 141 const MCOperand& MO0 = MI->getOperand(OpNo); 142 const MCOperand& MO1 = MI->getOperand(OpNo + 1); 143 144 O << getRegisterName(MO0.getReg()); 145 O << " + #" << MO1.getImm(); 146} 147 148void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo, 149 raw_ostream &O) const { 150 const MCOperand& MO0 = MI->getOperand(OpNo); 151 const MCOperand& MO1 = MI->getOperand(OpNo + 1); 152 153 O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm(); 154} 155 156void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo, 157 raw_ostream &O) const { 158 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); 159 160 printOperand(MI, OpNo, O); 161} 162 163void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo, 164 raw_ostream &O) const { 165 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); 166 167 printOperand(MI, OpNo, O); 168} 169 170void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo, 171 raw_ostream &O) const { 172 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); 173 174 printOperand(MI, OpNo, O); 175} 176 177void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, 178 raw_ostream &O) const { 179 // Branches can take an immediate operand. This is used by the branch 180 // selection pass to print $+8, an eight byte displacement from the PC. 181 llvm_unreachable("Unknown branch operand."); 182} 183 184void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo, 185 raw_ostream &O) const { 186} 187 188void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo, 189 raw_ostream &O) const { 190} 191 192void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, 193 raw_ostream &O) const { 194} 195 196void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo, 197 raw_ostream &O, bool hi) const { 198 assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand"); 199 200 O << '#' << (hi ? "HI" : "LO") << "(#"; 201 printOperand(MI, OpNo, O); 202 O << ')'; 203} 204