LLVM API Documentation
00001 //===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This class prints an PPC MCInst to a .s file. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #define DEBUG_TYPE "asm-printer" 00015 #include "PPCInstPrinter.h" 00016 #include "MCTargetDesc/PPCMCTargetDesc.h" 00017 #include "MCTargetDesc/PPCPredicates.h" 00018 #include "llvm/MC/MCExpr.h" 00019 #include "llvm/MC/MCInst.h" 00020 #include "llvm/MC/MCInstrInfo.h" 00021 #include "llvm/Support/raw_ostream.h" 00022 using namespace llvm; 00023 00024 #include "PPCGenAsmWriter.inc" 00025 00026 void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 00027 OS << getRegisterName(RegNo); 00028 } 00029 00030 void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 00031 StringRef Annot) { 00032 // Check for slwi/srwi mnemonics. 00033 if (MI->getOpcode() == PPC::RLWINM) { 00034 unsigned char SH = MI->getOperand(2).getImm(); 00035 unsigned char MB = MI->getOperand(3).getImm(); 00036 unsigned char ME = MI->getOperand(4).getImm(); 00037 bool useSubstituteMnemonic = false; 00038 if (SH <= 31 && MB == 0 && ME == (31-SH)) { 00039 O << "\tslwi "; useSubstituteMnemonic = true; 00040 } 00041 if (SH <= 31 && MB == (32-SH) && ME == 31) { 00042 O << "\tsrwi "; useSubstituteMnemonic = true; 00043 SH = 32-SH; 00044 } 00045 if (useSubstituteMnemonic) { 00046 printOperand(MI, 0, O); 00047 O << ", "; 00048 printOperand(MI, 1, O); 00049 O << ", " << (unsigned int)SH; 00050 00051 printAnnotation(O, Annot); 00052 return; 00053 } 00054 } 00055 00056 if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) && 00057 MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 00058 O << "\tmr "; 00059 printOperand(MI, 0, O); 00060 O << ", "; 00061 printOperand(MI, 1, O); 00062 printAnnotation(O, Annot); 00063 return; 00064 } 00065 00066 if (MI->getOpcode() == PPC::RLDICR) { 00067 unsigned char SH = MI->getOperand(2).getImm(); 00068 unsigned char ME = MI->getOperand(3).getImm(); 00069 // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH 00070 if (63-SH == ME) { 00071 O << "\tsldi "; 00072 printOperand(MI, 0, O); 00073 O << ", "; 00074 printOperand(MI, 1, O); 00075 O << ", " << (unsigned int)SH; 00076 printAnnotation(O, Annot); 00077 return; 00078 } 00079 } 00080 00081 printInstruction(MI, O); 00082 printAnnotation(O, Annot); 00083 } 00084 00085 00086 void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, 00087 raw_ostream &O, 00088 const char *Modifier) { 00089 unsigned Code = MI->getOperand(OpNo).getImm(); 00090 00091 if (StringRef(Modifier) == "cc") { 00092 switch ((PPC::Predicate)Code) { 00093 case PPC::PRED_LT: O << "lt"; return; 00094 case PPC::PRED_LE: O << "le"; return; 00095 case PPC::PRED_EQ: O << "eq"; return; 00096 case PPC::PRED_GE: O << "ge"; return; 00097 case PPC::PRED_GT: O << "gt"; return; 00098 case PPC::PRED_NE: O << "ne"; return; 00099 case PPC::PRED_UN: O << "un"; return; 00100 case PPC::PRED_NU: O << "nu"; return; 00101 } 00102 } 00103 00104 assert(StringRef(Modifier) == "reg" && 00105 "Need to specify 'cc' or 'reg' as predicate op modifier!"); 00106 printOperand(MI, OpNo+1, O); 00107 } 00108 00109 void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, 00110 raw_ostream &O) { 00111 int Value = MI->getOperand(OpNo).getImm(); 00112 Value = SignExtend32<5>(Value); 00113 O << (int)Value; 00114 } 00115 00116 void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, 00117 raw_ostream &O) { 00118 unsigned int Value = MI->getOperand(OpNo).getImm(); 00119 assert(Value <= 31 && "Invalid u5imm argument!"); 00120 O << (unsigned int)Value; 00121 } 00122 00123 void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, 00124 raw_ostream &O) { 00125 unsigned int Value = MI->getOperand(OpNo).getImm(); 00126 assert(Value <= 63 && "Invalid u6imm argument!"); 00127 O << (unsigned int)Value; 00128 } 00129 00130 void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, 00131 raw_ostream &O) { 00132 if (MI->getOperand(OpNo).isImm()) 00133 O << (short)MI->getOperand(OpNo).getImm(); 00134 else 00135 printOperand(MI, OpNo, O); 00136 } 00137 00138 void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, 00139 raw_ostream &O) { 00140 O << (unsigned short)MI->getOperand(OpNo).getImm(); 00141 } 00142 00143 void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, 00144 raw_ostream &O) { 00145 if (!MI->getOperand(OpNo).isImm()) 00146 return printOperand(MI, OpNo, O); 00147 00148 // Branches can take an immediate operand. This is used by the branch 00149 // selection pass to print .+8, an eight byte displacement from the PC. 00150 O << ".+"; 00151 printAbsAddrOperand(MI, OpNo, O); 00152 } 00153 00154 void PPCInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo, 00155 raw_ostream &O) { 00156 O << (int)MI->getOperand(OpNo).getImm()*4; 00157 } 00158 00159 00160 void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, 00161 raw_ostream &O) { 00162 unsigned CCReg = MI->getOperand(OpNo).getReg(); 00163 unsigned RegNo; 00164 switch (CCReg) { 00165 default: llvm_unreachable("Unknown CR register"); 00166 case PPC::CR0: RegNo = 0; break; 00167 case PPC::CR1: RegNo = 1; break; 00168 case PPC::CR2: RegNo = 2; break; 00169 case PPC::CR3: RegNo = 3; break; 00170 case PPC::CR4: RegNo = 4; break; 00171 case PPC::CR5: RegNo = 5; break; 00172 case PPC::CR6: RegNo = 6; break; 00173 case PPC::CR7: RegNo = 7; break; 00174 } 00175 O << (0x80 >> RegNo); 00176 } 00177 00178 void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, 00179 raw_ostream &O) { 00180 printS16ImmOperand(MI, OpNo, O); 00181 O << '('; 00182 if (MI->getOperand(OpNo+1).getReg() == PPC::R0) 00183 O << "0"; 00184 else 00185 printOperand(MI, OpNo+1, O); 00186 O << ')'; 00187 } 00188 00189 void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, 00190 raw_ostream &O) { 00191 // When used as the base register, r0 reads constant zero rather than 00192 // the value contained in the register. For this reason, the darwin 00193 // assembler requires that we print r0 as 0 (no r) when used as the base. 00194 if (MI->getOperand(OpNo).getReg() == PPC::R0) 00195 O << "0"; 00196 else 00197 printOperand(MI, OpNo, O); 00198 O << ", "; 00199 printOperand(MI, OpNo+1, O); 00200 } 00201 00202 00203 00204 /// stripRegisterPrefix - This method strips the character prefix from a 00205 /// register name so that only the number is left. Used by for linux asm. 00206 static const char *stripRegisterPrefix(const char *RegName) { 00207 switch (RegName[0]) { 00208 case 'r': 00209 case 'f': 00210 case 'v': return RegName + 1; 00211 case 'c': if (RegName[1] == 'r') return RegName + 2; 00212 } 00213 00214 return RegName; 00215 } 00216 00217 void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 00218 raw_ostream &O) { 00219 const MCOperand &Op = MI->getOperand(OpNo); 00220 if (Op.isReg()) { 00221 const char *RegName = getRegisterName(Op.getReg()); 00222 // The linux and AIX assembler does not take register prefixes. 00223 if (!isDarwinSyntax()) 00224 RegName = stripRegisterPrefix(RegName); 00225 00226 O << RegName; 00227 return; 00228 } 00229 00230 if (Op.isImm()) { 00231 O << Op.getImm(); 00232 return; 00233 } 00234 00235 assert(Op.isExpr() && "unknown operand kind in printOperand"); 00236 O << *Op.getExpr(); 00237 } 00238