1//===-- PPCInstPrinter.cpp - Convert PPC 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 PPC MCInst to a .s file. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "asm-printer" 15#include "PPCInstPrinter.h" 16#include "MCTargetDesc/PPCMCTargetDesc.h" 17#include "MCTargetDesc/PPCPredicates.h" 18#include "llvm/MC/MCExpr.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/MC/MCInstrInfo.h" 21#include "llvm/Support/raw_ostream.h" 22using namespace llvm; 23 24#include "PPCGenAsmWriter.inc" 25 26void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 27 OS << getRegisterName(RegNo); 28} 29 30void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 31 StringRef Annot) { 32 // Check for slwi/srwi mnemonics. 33 if (MI->getOpcode() == PPC::RLWINM) { 34 unsigned char SH = MI->getOperand(2).getImm(); 35 unsigned char MB = MI->getOperand(3).getImm(); 36 unsigned char ME = MI->getOperand(4).getImm(); 37 bool useSubstituteMnemonic = false; 38 if (SH <= 31 && MB == 0 && ME == (31-SH)) { 39 O << "\tslwi "; useSubstituteMnemonic = true; 40 } 41 if (SH <= 31 && MB == (32-SH) && ME == 31) { 42 O << "\tsrwi "; useSubstituteMnemonic = true; 43 SH = 32-SH; 44 } 45 if (useSubstituteMnemonic) { 46 printOperand(MI, 0, O); 47 O << ", "; 48 printOperand(MI, 1, O); 49 O << ", " << (unsigned int)SH; 50 51 printAnnotation(O, Annot); 52 return; 53 } 54 } 55 56 if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) && 57 MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 58 O << "\tmr "; 59 printOperand(MI, 0, O); 60 O << ", "; 61 printOperand(MI, 1, O); 62 printAnnotation(O, Annot); 63 return; 64 } 65 66 if (MI->getOpcode() == PPC::RLDICR) { 67 unsigned char SH = MI->getOperand(2).getImm(); 68 unsigned char ME = MI->getOperand(3).getImm(); 69 // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH 70 if (63-SH == ME) { 71 O << "\tsldi "; 72 printOperand(MI, 0, O); 73 O << ", "; 74 printOperand(MI, 1, O); 75 O << ", " << (unsigned int)SH; 76 printAnnotation(O, Annot); 77 return; 78 } 79 } 80 81 printInstruction(MI, O); 82 printAnnotation(O, Annot); 83} 84 85 86void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, 87 raw_ostream &O, 88 const char *Modifier) { 89 unsigned Code = MI->getOperand(OpNo).getImm(); 90 91 if (StringRef(Modifier) == "cc") { 92 switch ((PPC::Predicate)Code) { 93 case PPC::PRED_LT_MINUS: 94 case PPC::PRED_LT_PLUS: 95 case PPC::PRED_LT: 96 O << "lt"; 97 return; 98 case PPC::PRED_LE_MINUS: 99 case PPC::PRED_LE_PLUS: 100 case PPC::PRED_LE: 101 O << "le"; 102 return; 103 case PPC::PRED_EQ_MINUS: 104 case PPC::PRED_EQ_PLUS: 105 case PPC::PRED_EQ: 106 O << "eq"; 107 return; 108 case PPC::PRED_GE_MINUS: 109 case PPC::PRED_GE_PLUS: 110 case PPC::PRED_GE: 111 O << "ge"; 112 return; 113 case PPC::PRED_GT_MINUS: 114 case PPC::PRED_GT_PLUS: 115 case PPC::PRED_GT: 116 O << "gt"; 117 return; 118 case PPC::PRED_NE_MINUS: 119 case PPC::PRED_NE_PLUS: 120 case PPC::PRED_NE: 121 O << "ne"; 122 return; 123 case PPC::PRED_UN_MINUS: 124 case PPC::PRED_UN_PLUS: 125 case PPC::PRED_UN: 126 O << "un"; 127 return; 128 case PPC::PRED_NU_MINUS: 129 case PPC::PRED_NU_PLUS: 130 case PPC::PRED_NU: 131 O << "nu"; 132 return; 133 } 134 llvm_unreachable("Invalid predicate code"); 135 } 136 137 if (StringRef(Modifier) == "pm") { 138 switch ((PPC::Predicate)Code) { 139 case PPC::PRED_LT: 140 case PPC::PRED_LE: 141 case PPC::PRED_EQ: 142 case PPC::PRED_GE: 143 case PPC::PRED_GT: 144 case PPC::PRED_NE: 145 case PPC::PRED_UN: 146 case PPC::PRED_NU: 147 return; 148 case PPC::PRED_LT_MINUS: 149 case PPC::PRED_LE_MINUS: 150 case PPC::PRED_EQ_MINUS: 151 case PPC::PRED_GE_MINUS: 152 case PPC::PRED_GT_MINUS: 153 case PPC::PRED_NE_MINUS: 154 case PPC::PRED_UN_MINUS: 155 case PPC::PRED_NU_MINUS: 156 O << "-"; 157 return; 158 case PPC::PRED_LT_PLUS: 159 case PPC::PRED_LE_PLUS: 160 case PPC::PRED_EQ_PLUS: 161 case PPC::PRED_GE_PLUS: 162 case PPC::PRED_GT_PLUS: 163 case PPC::PRED_NE_PLUS: 164 case PPC::PRED_UN_PLUS: 165 case PPC::PRED_NU_PLUS: 166 O << "+"; 167 return; 168 } 169 llvm_unreachable("Invalid predicate code"); 170 } 171 172 assert(StringRef(Modifier) == "reg" && 173 "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!"); 174 printOperand(MI, OpNo+1, O); 175} 176 177void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, 178 raw_ostream &O) { 179 int Value = MI->getOperand(OpNo).getImm(); 180 Value = SignExtend32<5>(Value); 181 O << (int)Value; 182} 183 184void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, 185 raw_ostream &O) { 186 unsigned int Value = MI->getOperand(OpNo).getImm(); 187 assert(Value <= 31 && "Invalid u5imm argument!"); 188 O << (unsigned int)Value; 189} 190 191void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, 192 raw_ostream &O) { 193 unsigned int Value = MI->getOperand(OpNo).getImm(); 194 assert(Value <= 63 && "Invalid u6imm argument!"); 195 O << (unsigned int)Value; 196} 197 198void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, 199 raw_ostream &O) { 200 if (MI->getOperand(OpNo).isImm()) 201 O << (short)MI->getOperand(OpNo).getImm(); 202 else 203 printOperand(MI, OpNo, O); 204} 205 206void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, 207 raw_ostream &O) { 208 if (MI->getOperand(OpNo).isImm()) 209 O << (unsigned short)MI->getOperand(OpNo).getImm(); 210 else 211 printOperand(MI, OpNo, O); 212} 213 214void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, 215 raw_ostream &O) { 216 if (!MI->getOperand(OpNo).isImm()) 217 return printOperand(MI, OpNo, O); 218 219 // Branches can take an immediate operand. This is used by the branch 220 // selection pass to print .+8, an eight byte displacement from the PC. 221 O << ".+"; 222 printAbsBranchOperand(MI, OpNo, O); 223} 224 225void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, 226 raw_ostream &O) { 227 if (!MI->getOperand(OpNo).isImm()) 228 return printOperand(MI, OpNo, O); 229 230 O << (int)MI->getOperand(OpNo).getImm()*4; 231} 232 233 234void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, 235 raw_ostream &O) { 236 unsigned CCReg = MI->getOperand(OpNo).getReg(); 237 unsigned RegNo; 238 switch (CCReg) { 239 default: llvm_unreachable("Unknown CR register"); 240 case PPC::CR0: RegNo = 0; break; 241 case PPC::CR1: RegNo = 1; break; 242 case PPC::CR2: RegNo = 2; break; 243 case PPC::CR3: RegNo = 3; break; 244 case PPC::CR4: RegNo = 4; break; 245 case PPC::CR5: RegNo = 5; break; 246 case PPC::CR6: RegNo = 6; break; 247 case PPC::CR7: RegNo = 7; break; 248 } 249 O << (0x80 >> RegNo); 250} 251 252void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, 253 raw_ostream &O) { 254 printS16ImmOperand(MI, OpNo, O); 255 O << '('; 256 if (MI->getOperand(OpNo+1).getReg() == PPC::R0) 257 O << "0"; 258 else 259 printOperand(MI, OpNo+1, O); 260 O << ')'; 261} 262 263void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, 264 raw_ostream &O) { 265 // When used as the base register, r0 reads constant zero rather than 266 // the value contained in the register. For this reason, the darwin 267 // assembler requires that we print r0 as 0 (no r) when used as the base. 268 if (MI->getOperand(OpNo).getReg() == PPC::R0) 269 O << "0"; 270 else 271 printOperand(MI, OpNo, O); 272 O << ", "; 273 printOperand(MI, OpNo+1, O); 274} 275 276void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo, 277 raw_ostream &O) { 278 printBranchOperand(MI, OpNo, O); 279 O << '('; 280 printOperand(MI, OpNo+1, O); 281 O << ')'; 282} 283 284 285/// stripRegisterPrefix - This method strips the character prefix from a 286/// register name so that only the number is left. Used by for linux asm. 287static const char *stripRegisterPrefix(const char *RegName) { 288 switch (RegName[0]) { 289 case 'r': 290 case 'f': 291 case 'v': return RegName + 1; 292 case 'c': if (RegName[1] == 'r') return RegName + 2; 293 } 294 295 return RegName; 296} 297 298void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 299 raw_ostream &O) { 300 const MCOperand &Op = MI->getOperand(OpNo); 301 if (Op.isReg()) { 302 const char *RegName = getRegisterName(Op.getReg()); 303 // The linux and AIX assembler does not take register prefixes. 304 if (!isDarwinSyntax()) 305 RegName = stripRegisterPrefix(RegName); 306 307 O << RegName; 308 return; 309 } 310 311 if (Op.isImm()) { 312 O << Op.getImm(); 313 return; 314 } 315 316 assert(Op.isExpr() && "unknown operand kind in printOperand"); 317 O << *Op.getExpr(); 318} 319 320