SparcInstPrinter.cpp revision 263763
1//===-- SparcInstPrinter.cpp - Convert Sparc 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 Sparc MCInst to a .s file. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "asm-printer" 15#include "SparcInstPrinter.h" 16 17#include "Sparc.h" 18#include "llvm/MC/MCExpr.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/MC/MCSymbol.h" 21#include "llvm/Support/raw_ostream.h" 22using namespace llvm; 23 24#define GET_INSTRUCTION_NAME 25#define PRINT_ALIAS_INSTR 26#include "SparcGenAsmWriter.inc" 27 28void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const 29{ 30 OS << '%' << StringRef(getRegisterName(RegNo)).lower(); 31} 32 33void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 34 StringRef Annot) 35{ 36 if (!printAliasInstr(MI, O) && !printSparcAliasInstr(MI, O)) 37 printInstruction(MI, O); 38 printAnnotation(O, Annot); 39} 40 41bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O) 42{ 43 switch (MI->getOpcode()) { 44 default: return false; 45 case SP::JMPLrr: 46 case SP::JMPLri: { 47 if (MI->getNumOperands() != 3) 48 return false; 49 if (!MI->getOperand(0).isReg()) 50 return false; 51 switch (MI->getOperand(0).getReg()) { 52 default: return false; 53 case SP::G0: // jmp $addr 54 O << "\tjmp "; printMemOperand(MI, 1, O); 55 return true; 56 case SP::O7: // call $addr 57 O << "\tcall "; printMemOperand(MI, 1, O); 58 return true; 59 } 60 } 61 } 62} 63 64void SparcInstPrinter::printOperand(const MCInst *MI, int opNum, 65 raw_ostream &O) 66{ 67 const MCOperand &MO = MI->getOperand (opNum); 68 69 if (MO.isReg()) { 70 printRegName(O, MO.getReg()); 71 return ; 72 } 73 74 if (MO.isImm()) { 75 O << (int)MO.getImm(); 76 return; 77 } 78 79 assert(MO.isExpr() && "Unknown operand kind in printOperand"); 80 MO.getExpr()->print(O); 81} 82 83void SparcInstPrinter::printMemOperand(const MCInst *MI, int opNum, 84 raw_ostream &O, const char *Modifier) 85{ 86 printOperand(MI, opNum, O); 87 88 // If this is an ADD operand, emit it like normal operands. 89 if (Modifier && !strcmp(Modifier, "arith")) { 90 O << ", "; 91 printOperand(MI, opNum+1, O); 92 return; 93 } 94 const MCOperand &MO = MI->getOperand(opNum+1); 95 96 if (MO.isReg() && MO.getReg() == SP::G0) 97 return; // don't print "+%g0" 98 if (MO.isImm() && MO.getImm() == 0) 99 return; // don't print "+0" 100 101 O << "+"; 102 103 printOperand(MI, opNum+1, O); 104} 105 106void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum, 107 raw_ostream &O) 108{ 109 int CC = (int)MI->getOperand(opNum).getImm(); 110 switch (MI->getOpcode()) { 111 default: break; 112 case SP::FBCOND: 113 case SP::MOVFCCrr: 114 case SP::MOVFCCri: 115 case SP::FMOVS_FCC: 116 case SP::FMOVD_FCC: 117 case SP::FMOVQ_FCC: // Make sure CC is a fp conditional flag. 118 CC = (CC < 16) ? (CC + 16) : CC; 119 break; 120 } 121 O << SPARCCondCodeToString((SPCC::CondCodes)CC); 122} 123 124bool SparcInstPrinter::printGetPCX(const MCInst *MI, unsigned opNum, 125 raw_ostream &O) 126{ 127 assert(0 && "FIXME: Implement SparcInstPrinter::printGetPCX."); 128 return true; 129} 130