diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp index 9cc1c539e24a..16da62a74b8c 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp @@ -116,16 +116,6 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address, } } - if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) && - MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { - O << "\tmr "; - printOperand(MI, 0, O); - O << ", "; - printOperand(MI, 1, O); - printAnnotation(O, Annot); - return; - } - if (MI->getOpcode() == PPC::RLDICR || MI->getOpcode() == PPC::RLDICR_32) { unsigned char SH = MI->getOperand(2).getImm(); @@ -193,7 +183,7 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address, } } - if (!printAliasInstr(MI, O)) + if (!printAliasInstr(MI, Address, O)) printInstruction(MI, Address, O); printAnnotation(O, Annot); } @@ -339,6 +329,13 @@ void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, O << (int)Value; } +void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value == 0 && "Operand must be zero"); + O << (unsigned int)Value; +} + void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { unsigned int Value = MI->getOperand(OpNo).getImm(); @@ -391,6 +388,17 @@ void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, printOperand(MI, OpNo, O); } +void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + if (MI->getOperand(OpNo).isImm()) { + long long Value = MI->getOperand(OpNo).getImm(); + assert(isInt<34>(Value) && "Invalid s34imm argument!"); + O << (long long)Value; + } + else + printOperand(MI, OpNo, O); +} + void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { if (MI->getOperand(OpNo).isImm()) @@ -399,18 +407,29 @@ void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, printOperand(MI, OpNo, O); } -void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) { +void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address, + unsigned OpNo, raw_ostream &O) { if (!MI->getOperand(OpNo).isImm()) return printOperand(MI, OpNo, O); - - // Branches can take an immediate operand. This is used by the branch - // selection pass to print .+8, an eight byte displacement from the PC. - O << "."; int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); - if (Imm >= 0) - O << "+"; - O << Imm; + if (PrintBranchImmAsAddress) { + uint64_t Target = Address + Imm; + if (!TT.isPPC64()) + Target &= 0xffffffff; + O << formatHex(Target); + } else { + // Branches can take an immediate operand. This is used by the branch + // selection pass to print, for example `.+8` (for ELF) or `$+8` (for AIX) + // to express an eight byte displacement from the program counter. + if (!TT.isOSAIX()) + O << "."; + else + O << "$"; + + if (Imm >= 0) + O << "+"; + O << Imm; + } } void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, @@ -451,6 +470,22 @@ void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, O << ')'; } +void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + printS34ImmOperand(MI, OpNo, O); + O << '('; + printImmZeroOperand(MI, OpNo + 1, O); + O << ')'; +} + +void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + printS34ImmOperand(MI, OpNo, O); + O << '('; + printOperand(MI, OpNo + 1, O); + O << ')'; +} + void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, raw_ostream &O) { // When used as the base register, r0 reads constant zero rather than |