PPCInstPrinter.cpp revision 0a2f793d6e24acd00d9209b46436b4899feb1cdb
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/PPCBaseInfo.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 if (!Modifier) { 91 unsigned CCReg = MI->getOperand(OpNo+1).getReg(); 92 unsigned RegNo; 93 switch (CCReg) { 94 default: llvm_unreachable("Unknown CR register"); 95 case PPC::CR0: RegNo = 0; break; 96 case PPC::CR1: RegNo = 1; break; 97 case PPC::CR2: RegNo = 2; break; 98 case PPC::CR3: RegNo = 3; break; 99 case PPC::CR4: RegNo = 4; break; 100 case PPC::CR5: RegNo = 5; break; 101 case PPC::CR6: RegNo = 6; break; 102 case PPC::CR7: RegNo = 7; break; 103 } 104 105 // Print the CR bit number. The Code is ((BI << 5) | BO) for a 106 // BCC, but we must have the positive form here (BO == 12) 107 unsigned BI = Code >> 5; 108 assert((Code & 0xF) == 12 && 109 "BO in predicate bit must have the positive form"); 110 111 unsigned Value = 4*RegNo + BI; 112 O << Value; 113 return; 114 } 115 116 if (StringRef(Modifier) == "cc") { 117 switch ((PPC::Predicate)Code) { 118 case PPC::PRED_ALWAYS: return; // Don't print anything for always. 119 case PPC::PRED_LT: O << "lt"; return; 120 case PPC::PRED_LE: O << "le"; return; 121 case PPC::PRED_EQ: O << "eq"; return; 122 case PPC::PRED_GE: O << "ge"; return; 123 case PPC::PRED_GT: O << "gt"; return; 124 case PPC::PRED_NE: O << "ne"; return; 125 case PPC::PRED_UN: O << "un"; return; 126 case PPC::PRED_NU: O << "nu"; return; 127 } 128 } 129 130 assert(StringRef(Modifier) == "reg" && 131 "Need to specify 'cc' or 'reg' as predicate op modifier!"); 132 // Don't print the register for 'always'. 133 if (Code == PPC::PRED_ALWAYS) return; 134 printOperand(MI, OpNo+1, O); 135} 136 137void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, 138 raw_ostream &O) { 139 char Value = MI->getOperand(OpNo).getImm(); 140 Value = (Value << (32-5)) >> (32-5); 141 O << (int)Value; 142} 143 144void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, 145 raw_ostream &O) { 146 unsigned char Value = MI->getOperand(OpNo).getImm(); 147 assert(Value <= 31 && "Invalid u5imm argument!"); 148 O << (unsigned int)Value; 149} 150 151void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, 152 raw_ostream &O) { 153 unsigned char Value = MI->getOperand(OpNo).getImm(); 154 assert(Value <= 63 && "Invalid u6imm argument!"); 155 O << (unsigned int)Value; 156} 157 158void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, 159 raw_ostream &O) { 160 O << (short)MI->getOperand(OpNo).getImm(); 161} 162 163void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, 164 raw_ostream &O) { 165 O << (unsigned short)MI->getOperand(OpNo).getImm(); 166} 167 168void PPCInstPrinter::printS16X4ImmOperand(const MCInst *MI, unsigned OpNo, 169 raw_ostream &O) { 170 if (MI->getOperand(OpNo).isImm()) 171 O << (short)(MI->getOperand(OpNo).getImm()*4); 172 else 173 printOperand(MI, OpNo, O); 174} 175 176void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, 177 raw_ostream &O) { 178 if (!MI->getOperand(OpNo).isImm()) 179 return printOperand(MI, OpNo, O); 180 181 // Branches can take an immediate operand. This is used by the branch 182 // selection pass to print $+8, an eight byte displacement from the PC. 183 O << "$+"; 184 printAbsAddrOperand(MI, OpNo, O); 185} 186 187void PPCInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo, 188 raw_ostream &O) { 189 O << (int)MI->getOperand(OpNo).getImm()*4; 190} 191 192 193void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, 194 raw_ostream &O) { 195 unsigned CCReg = MI->getOperand(OpNo).getReg(); 196 unsigned RegNo; 197 switch (CCReg) { 198 default: llvm_unreachable("Unknown CR register"); 199 case PPC::CR0: RegNo = 0; break; 200 case PPC::CR1: RegNo = 1; break; 201 case PPC::CR2: RegNo = 2; break; 202 case PPC::CR3: RegNo = 3; break; 203 case PPC::CR4: RegNo = 4; break; 204 case PPC::CR5: RegNo = 5; break; 205 case PPC::CR6: RegNo = 6; break; 206 case PPC::CR7: RegNo = 7; break; 207 } 208 O << (0x80 >> RegNo); 209} 210 211void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, 212 raw_ostream &O) { 213 printSymbolLo(MI, OpNo, O); 214 O << '('; 215 if (MI->getOperand(OpNo+1).getReg() == PPC::R0) 216 O << "0"; 217 else 218 printOperand(MI, OpNo+1, O); 219 O << ')'; 220} 221 222void PPCInstPrinter::printMemRegImmShifted(const MCInst *MI, unsigned OpNo, 223 raw_ostream &O) { 224 if (MI->getOperand(OpNo).isImm()) 225 printS16X4ImmOperand(MI, OpNo, O); 226 else 227 printSymbolLo(MI, OpNo, O); 228 O << '('; 229 230 if (MI->getOperand(OpNo+1).getReg() == PPC::R0) 231 O << "0"; 232 else 233 printOperand(MI, OpNo+1, O); 234 O << ')'; 235} 236 237 238void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, 239 raw_ostream &O) { 240 // When used as the base register, r0 reads constant zero rather than 241 // the value contained in the register. For this reason, the darwin 242 // assembler requires that we print r0 as 0 (no r) when used as the base. 243 if (MI->getOperand(OpNo).getReg() == PPC::R0) 244 O << "0"; 245 else 246 printOperand(MI, OpNo, O); 247 O << ", "; 248 printOperand(MI, OpNo+1, O); 249} 250 251 252 253/// stripRegisterPrefix - This method strips the character prefix from a 254/// register name so that only the number is left. Used by for linux asm. 255static const char *stripRegisterPrefix(const char *RegName) { 256 switch (RegName[0]) { 257 case 'r': 258 case 'f': 259 case 'v': return RegName + 1; 260 case 'c': if (RegName[1] == 'r') return RegName + 2; 261 } 262 263 return RegName; 264} 265 266void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 267 raw_ostream &O) { 268 const MCOperand &Op = MI->getOperand(OpNo); 269 if (Op.isReg()) { 270 const char *RegName = getRegisterName(Op.getReg()); 271 // The linux and AIX assembler does not take register prefixes. 272 if (!isDarwinSyntax()) 273 RegName = stripRegisterPrefix(RegName); 274 275 O << RegName; 276 return; 277 } 278 279 if (Op.isImm()) { 280 O << Op.getImm(); 281 return; 282 } 283 284 assert(Op.isExpr() && "unknown operand kind in printOperand"); 285 O << *Op.getExpr(); 286} 287 288void PPCInstPrinter::printSymbolLo(const MCInst *MI, unsigned OpNo, 289 raw_ostream &O) { 290 if (MI->getOperand(OpNo).isImm()) 291 return printS16ImmOperand(MI, OpNo, O); 292 293 // FIXME: This is a terrible hack because we can't encode lo16() as an operand 294 // flag of a subtraction. See the FIXME in GetSymbolRef in PPCMCInstLower. 295 if (MI->getOperand(OpNo).isExpr() && 296 isa<MCBinaryExpr>(MI->getOperand(OpNo).getExpr())) { 297 O << "lo16("; 298 printOperand(MI, OpNo, O); 299 O << ')'; 300 } else { 301 printOperand(MI, OpNo, O); 302 } 303} 304 305void PPCInstPrinter::printSymbolHi(const MCInst *MI, unsigned OpNo, 306 raw_ostream &O) { 307 if (MI->getOperand(OpNo).isImm()) 308 return printS16ImmOperand(MI, OpNo, O); 309 310 // FIXME: This is a terrible hack because we can't encode lo16() as an operand 311 // flag of a subtraction. See the FIXME in GetSymbolRef in PPCMCInstLower. 312 if (MI->getOperand(OpNo).isExpr() && 313 isa<MCBinaryExpr>(MI->getOperand(OpNo).getExpr())) { 314 O << "ha16("; 315 printOperand(MI, OpNo, O); 316 O << ')'; 317 } else { 318 printOperand(MI, OpNo, O); 319 } 320} 321 322 323