1218885Sdim//===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This class prints an PPC MCInst to a .s file. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14218885Sdim#define DEBUG_TYPE "asm-printer" 15218885Sdim#include "PPCInstPrinter.h" 16249423Sdim#include "MCTargetDesc/PPCMCTargetDesc.h" 17226633Sdim#include "MCTargetDesc/PPCPredicates.h" 18218885Sdim#include "llvm/MC/MCExpr.h" 19218885Sdim#include "llvm/MC/MCInst.h" 20234353Sdim#include "llvm/MC/MCInstrInfo.h" 21263508Sdim#include "llvm/Support/CommandLine.h" 22218885Sdim#include "llvm/Support/raw_ostream.h" 23263508Sdim#include "llvm/Target/TargetOpcodes.h" 24218885Sdimusing namespace llvm; 25218885Sdim 26263508Sdim// FIXME: Once the integrated assembler supports full register names, tie this 27263508Sdim// to the verbose-asm setting. 28263508Sdimstatic cl::opt<bool> 29263508SdimFullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false), 30263508Sdim cl::desc("Use full register names when printing assembly")); 31263508Sdim 32218885Sdim#include "PPCGenAsmWriter.inc" 33218885Sdim 34223017Sdimvoid PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 35223017Sdim OS << getRegisterName(RegNo); 36223017Sdim} 37218885Sdim 38226633Sdimvoid PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 39226633Sdim StringRef Annot) { 40218885Sdim // Check for slwi/srwi mnemonics. 41218885Sdim if (MI->getOpcode() == PPC::RLWINM) { 42218885Sdim unsigned char SH = MI->getOperand(2).getImm(); 43218885Sdim unsigned char MB = MI->getOperand(3).getImm(); 44218885Sdim unsigned char ME = MI->getOperand(4).getImm(); 45218885Sdim bool useSubstituteMnemonic = false; 46218885Sdim if (SH <= 31 && MB == 0 && ME == (31-SH)) { 47218885Sdim O << "\tslwi "; useSubstituteMnemonic = true; 48218885Sdim } 49218885Sdim if (SH <= 31 && MB == (32-SH) && ME == 31) { 50218885Sdim O << "\tsrwi "; useSubstituteMnemonic = true; 51218885Sdim SH = 32-SH; 52218885Sdim } 53218885Sdim if (useSubstituteMnemonic) { 54218885Sdim printOperand(MI, 0, O); 55218885Sdim O << ", "; 56218885Sdim printOperand(MI, 1, O); 57218885Sdim O << ", " << (unsigned int)SH; 58226633Sdim 59226633Sdim printAnnotation(O, Annot); 60218885Sdim return; 61218885Sdim } 62218885Sdim } 63218885Sdim 64218885Sdim if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) && 65218885Sdim MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 66218885Sdim O << "\tmr "; 67218885Sdim printOperand(MI, 0, O); 68218885Sdim O << ", "; 69218885Sdim printOperand(MI, 1, O); 70226633Sdim printAnnotation(O, Annot); 71218885Sdim return; 72218885Sdim } 73218885Sdim 74218885Sdim if (MI->getOpcode() == PPC::RLDICR) { 75218885Sdim unsigned char SH = MI->getOperand(2).getImm(); 76218885Sdim unsigned char ME = MI->getOperand(3).getImm(); 77218885Sdim // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH 78218885Sdim if (63-SH == ME) { 79218885Sdim O << "\tsldi "; 80218885Sdim printOperand(MI, 0, O); 81218885Sdim O << ", "; 82218885Sdim printOperand(MI, 1, O); 83218885Sdim O << ", " << (unsigned int)SH; 84226633Sdim printAnnotation(O, Annot); 85218885Sdim return; 86218885Sdim } 87218885Sdim } 88218885Sdim 89263508Sdim // For fast-isel, a COPY_TO_REGCLASS may survive this long. This is 90263508Sdim // used when converting a 32-bit float to a 64-bit float as part of 91263508Sdim // conversion to an integer (see PPCFastISel.cpp:SelectFPToI()), 92263508Sdim // as otherwise we have problems with incorrect register classes 93263508Sdim // in machine instruction verification. For now, just avoid trying 94263508Sdim // to print it as such an instruction has no effect (a 32-bit float 95263508Sdim // in a register is already in 64-bit form, just with lower 96263508Sdim // precision). FIXME: Is there a better solution? 97263508Sdim if (MI->getOpcode() == TargetOpcode::COPY_TO_REGCLASS) 98263508Sdim return; 99263508Sdim 100218885Sdim printInstruction(MI, O); 101226633Sdim printAnnotation(O, Annot); 102218885Sdim} 103218885Sdim 104218885Sdim 105218885Sdimvoid PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, 106218885Sdim raw_ostream &O, 107218885Sdim const char *Modifier) { 108218885Sdim unsigned Code = MI->getOperand(OpNo).getImm(); 109239462Sdim 110218885Sdim if (StringRef(Modifier) == "cc") { 111218885Sdim switch ((PPC::Predicate)Code) { 112263508Sdim case PPC::PRED_LT_MINUS: 113263508Sdim case PPC::PRED_LT_PLUS: 114263508Sdim case PPC::PRED_LT: 115263508Sdim O << "lt"; 116263508Sdim return; 117263508Sdim case PPC::PRED_LE_MINUS: 118263508Sdim case PPC::PRED_LE_PLUS: 119263508Sdim case PPC::PRED_LE: 120263508Sdim O << "le"; 121263508Sdim return; 122263508Sdim case PPC::PRED_EQ_MINUS: 123263508Sdim case PPC::PRED_EQ_PLUS: 124263508Sdim case PPC::PRED_EQ: 125263508Sdim O << "eq"; 126263508Sdim return; 127263508Sdim case PPC::PRED_GE_MINUS: 128263508Sdim case PPC::PRED_GE_PLUS: 129263508Sdim case PPC::PRED_GE: 130263508Sdim O << "ge"; 131263508Sdim return; 132263508Sdim case PPC::PRED_GT_MINUS: 133263508Sdim case PPC::PRED_GT_PLUS: 134263508Sdim case PPC::PRED_GT: 135263508Sdim O << "gt"; 136263508Sdim return; 137263508Sdim case PPC::PRED_NE_MINUS: 138263508Sdim case PPC::PRED_NE_PLUS: 139263508Sdim case PPC::PRED_NE: 140263508Sdim O << "ne"; 141263508Sdim return; 142263508Sdim case PPC::PRED_UN_MINUS: 143263508Sdim case PPC::PRED_UN_PLUS: 144263508Sdim case PPC::PRED_UN: 145263508Sdim O << "un"; 146263508Sdim return; 147263508Sdim case PPC::PRED_NU_MINUS: 148263508Sdim case PPC::PRED_NU_PLUS: 149263508Sdim case PPC::PRED_NU: 150263508Sdim O << "nu"; 151263508Sdim return; 152218885Sdim } 153263508Sdim llvm_unreachable("Invalid predicate code"); 154218885Sdim } 155263508Sdim 156263508Sdim if (StringRef(Modifier) == "pm") { 157263508Sdim switch ((PPC::Predicate)Code) { 158263508Sdim case PPC::PRED_LT: 159263508Sdim case PPC::PRED_LE: 160263508Sdim case PPC::PRED_EQ: 161263508Sdim case PPC::PRED_GE: 162263508Sdim case PPC::PRED_GT: 163263508Sdim case PPC::PRED_NE: 164263508Sdim case PPC::PRED_UN: 165263508Sdim case PPC::PRED_NU: 166263508Sdim return; 167263508Sdim case PPC::PRED_LT_MINUS: 168263508Sdim case PPC::PRED_LE_MINUS: 169263508Sdim case PPC::PRED_EQ_MINUS: 170263508Sdim case PPC::PRED_GE_MINUS: 171263508Sdim case PPC::PRED_GT_MINUS: 172263508Sdim case PPC::PRED_NE_MINUS: 173263508Sdim case PPC::PRED_UN_MINUS: 174263508Sdim case PPC::PRED_NU_MINUS: 175263508Sdim O << "-"; 176263508Sdim return; 177263508Sdim case PPC::PRED_LT_PLUS: 178263508Sdim case PPC::PRED_LE_PLUS: 179263508Sdim case PPC::PRED_EQ_PLUS: 180263508Sdim case PPC::PRED_GE_PLUS: 181263508Sdim case PPC::PRED_GT_PLUS: 182263508Sdim case PPC::PRED_NE_PLUS: 183263508Sdim case PPC::PRED_UN_PLUS: 184263508Sdim case PPC::PRED_NU_PLUS: 185263508Sdim O << "+"; 186263508Sdim return; 187263508Sdim } 188263508Sdim llvm_unreachable("Invalid predicate code"); 189263508Sdim } 190218885Sdim 191218885Sdim assert(StringRef(Modifier) == "reg" && 192263508Sdim "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!"); 193218885Sdim printOperand(MI, OpNo+1, O); 194218885Sdim} 195218885Sdim 196218885Sdimvoid PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, 197218885Sdim raw_ostream &O) { 198243830Sdim int Value = MI->getOperand(OpNo).getImm(); 199243830Sdim Value = SignExtend32<5>(Value); 200218885Sdim O << (int)Value; 201218885Sdim} 202218885Sdim 203218885Sdimvoid PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, 204218885Sdim raw_ostream &O) { 205243830Sdim unsigned int Value = MI->getOperand(OpNo).getImm(); 206218885Sdim assert(Value <= 31 && "Invalid u5imm argument!"); 207218885Sdim O << (unsigned int)Value; 208218885Sdim} 209218885Sdim 210218885Sdimvoid PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, 211218885Sdim raw_ostream &O) { 212243830Sdim unsigned int Value = MI->getOperand(OpNo).getImm(); 213218885Sdim assert(Value <= 63 && "Invalid u6imm argument!"); 214218885Sdim O << (unsigned int)Value; 215218885Sdim} 216218885Sdim 217218885Sdimvoid PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, 218218885Sdim raw_ostream &O) { 219263508Sdim if (MI->getOperand(OpNo).isImm()) 220263508Sdim O << (short)MI->getOperand(OpNo).getImm(); 221263508Sdim else 222263508Sdim printOperand(MI, OpNo, O); 223218885Sdim} 224218885Sdim 225218885Sdimvoid PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, 226218885Sdim raw_ostream &O) { 227218885Sdim if (MI->getOperand(OpNo).isImm()) 228263508Sdim O << (unsigned short)MI->getOperand(OpNo).getImm(); 229218885Sdim else 230218885Sdim printOperand(MI, OpNo, O); 231218885Sdim} 232218885Sdim 233218885Sdimvoid PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, 234218885Sdim raw_ostream &O) { 235218885Sdim if (!MI->getOperand(OpNo).isImm()) 236218885Sdim return printOperand(MI, OpNo, O); 237218885Sdim 238218885Sdim // Branches can take an immediate operand. This is used by the branch 239251662Sdim // selection pass to print .+8, an eight byte displacement from the PC. 240251662Sdim O << ".+"; 241263508Sdim printAbsBranchOperand(MI, OpNo, O); 242218885Sdim} 243218885Sdim 244263508Sdimvoid PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, 245263508Sdim raw_ostream &O) { 246263508Sdim if (!MI->getOperand(OpNo).isImm()) 247263508Sdim return printOperand(MI, OpNo, O); 248263508Sdim 249218885Sdim O << (int)MI->getOperand(OpNo).getImm()*4; 250218885Sdim} 251218885Sdim 252218885Sdim 253218885Sdimvoid PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, 254218885Sdim raw_ostream &O) { 255218885Sdim unsigned CCReg = MI->getOperand(OpNo).getReg(); 256218885Sdim unsigned RegNo; 257218885Sdim switch (CCReg) { 258234353Sdim default: llvm_unreachable("Unknown CR register"); 259218885Sdim case PPC::CR0: RegNo = 0; break; 260218885Sdim case PPC::CR1: RegNo = 1; break; 261218885Sdim case PPC::CR2: RegNo = 2; break; 262218885Sdim case PPC::CR3: RegNo = 3; break; 263218885Sdim case PPC::CR4: RegNo = 4; break; 264218885Sdim case PPC::CR5: RegNo = 5; break; 265218885Sdim case PPC::CR6: RegNo = 6; break; 266218885Sdim case PPC::CR7: RegNo = 7; break; 267218885Sdim } 268218885Sdim O << (0x80 >> RegNo); 269218885Sdim} 270218885Sdim 271218885Sdimvoid PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, 272218885Sdim raw_ostream &O) { 273263508Sdim printS16ImmOperand(MI, OpNo, O); 274218885Sdim O << '('; 275218885Sdim if (MI->getOperand(OpNo+1).getReg() == PPC::R0) 276218885Sdim O << "0"; 277218885Sdim else 278218885Sdim printOperand(MI, OpNo+1, O); 279218885Sdim O << ')'; 280218885Sdim} 281218885Sdim 282218885Sdimvoid PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, 283218885Sdim raw_ostream &O) { 284218885Sdim // When used as the base register, r0 reads constant zero rather than 285218885Sdim // the value contained in the register. For this reason, the darwin 286218885Sdim // assembler requires that we print r0 as 0 (no r) when used as the base. 287218885Sdim if (MI->getOperand(OpNo).getReg() == PPC::R0) 288218885Sdim O << "0"; 289218885Sdim else 290218885Sdim printOperand(MI, OpNo, O); 291218885Sdim O << ", "; 292218885Sdim printOperand(MI, OpNo+1, O); 293218885Sdim} 294218885Sdim 295263508Sdimvoid PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo, 296263508Sdim raw_ostream &O) { 297263508Sdim printBranchOperand(MI, OpNo, O); 298263508Sdim O << '('; 299263508Sdim printOperand(MI, OpNo+1, O); 300263508Sdim O << ')'; 301263508Sdim} 302218885Sdim 303218885Sdim 304218885Sdim/// stripRegisterPrefix - This method strips the character prefix from a 305218885Sdim/// register name so that only the number is left. Used by for linux asm. 306218885Sdimstatic const char *stripRegisterPrefix(const char *RegName) { 307263508Sdim if (FullRegNames) 308263508Sdim return RegName; 309263508Sdim 310218885Sdim switch (RegName[0]) { 311218885Sdim case 'r': 312218885Sdim case 'f': 313218885Sdim case 'v': return RegName + 1; 314218885Sdim case 'c': if (RegName[1] == 'r') return RegName + 2; 315218885Sdim } 316218885Sdim 317218885Sdim return RegName; 318218885Sdim} 319218885Sdim 320218885Sdimvoid PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 321218885Sdim raw_ostream &O) { 322218885Sdim const MCOperand &Op = MI->getOperand(OpNo); 323218885Sdim if (Op.isReg()) { 324218885Sdim const char *RegName = getRegisterName(Op.getReg()); 325218885Sdim // The linux and AIX assembler does not take register prefixes. 326218885Sdim if (!isDarwinSyntax()) 327218885Sdim RegName = stripRegisterPrefix(RegName); 328218885Sdim 329218885Sdim O << RegName; 330218885Sdim return; 331218885Sdim } 332218885Sdim 333218885Sdim if (Op.isImm()) { 334218885Sdim O << Op.getImm(); 335218885Sdim return; 336218885Sdim } 337218885Sdim 338218885Sdim assert(Op.isExpr() && "unknown operand kind in printOperand"); 339218885Sdim O << *Op.getExpr(); 340218885Sdim} 341218885Sdim 342