summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp')
-rw-r--r--lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp61
1 files changed, 57 insertions, 4 deletions
diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
index d9d9b4f180f7..609d959c6d08 100644
--- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
+++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "PPCInstPrinter.h"
+#include "PPCInstrInfo.h"
#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "llvm/MC/MCExpr.h"
@@ -33,6 +34,11 @@ static cl::opt<bool>
FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
cl::desc("Use full register names when printing assembly"));
+// Useful for testing purposes. Prints vs{31-63} as v{0-31} respectively.
+static cl::opt<bool>
+ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false),
+ cl::desc("Prints full register names with vs{31-63} as v{0-31}"));
+
#define PRINT_ALIAS_INSTR
#include "PPCGenAsmWriter.inc"
@@ -135,6 +141,25 @@ void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
printAnnotation(O, Annot);
return;
}
+
+ if (MI->getOpcode() == PPC::DCBF) {
+ unsigned char L = MI->getOperand(0).getImm();
+ if (!L || L == 1 || L == 3) {
+ O << "\tdcbf";
+ if (L == 1 || L == 3)
+ O << "l";
+ if (L == 3)
+ O << "p";
+ O << " ";
+
+ printOperand(MI, 1, O);
+ O << ", ";
+ printOperand(MI, 2, O);
+
+ printAnnotation(O, Annot);
+ return;
+ }
+ }
if (!printAliasInstr(MI, O))
printInstruction(MI, O);
@@ -239,6 +264,15 @@ void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
printOperand(MI, OpNo+1, O);
}
+void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ unsigned Code = MI->getOperand(OpNo).getImm();
+ if (Code == 2)
+ O << "-";
+ else if (Code == 3)
+ O << "+";
+}
+
void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
@@ -295,10 +329,12 @@ void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
O << (unsigned int)Value;
}
+// Operands of BUILD_VECTOR are signed and we use this to print operands
+// of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
+// print as unsigned.
void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
- unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 255 && "Invalid u8imm argument!");
+ unsigned char Value = MI->getOperand(OpNo).getImm();
O << (unsigned int)Value;
}
@@ -412,7 +448,7 @@ void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
/// stripRegisterPrefix - This method strips the character prefix from a
/// register name so that only the number is left. Used by for linux asm.
static const char *stripRegisterPrefix(const char *RegName) {
- if (FullRegNames)
+ if (FullRegNames || ShowVSRNumsAsVR)
return RegName;
switch (RegName[0]) {
@@ -433,7 +469,24 @@ void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
- const char *RegName = getRegisterName(Op.getReg());
+ unsigned Reg = Op.getReg();
+
+ // There are VSX instructions that use VSX register numbering (vs0 - vs63)
+ // as well as those that use VMX register numbering (v0 - v31 which
+ // correspond to vs32 - vs63). If we have an instruction that uses VSX
+ // numbering, we need to convert the VMX registers to VSX registers.
+ // Namely, we print 32-63 when the instruction operates on one of the
+ // VMX registers.
+ // (Please synchronize with PPCAsmPrinter::printOperand)
+ if ((MII.get(MI->getOpcode()).TSFlags & PPCII::UseVSXReg) &&
+ !ShowVSRNumsAsVR) {
+ if (PPCInstrInfo::isVRRegister(Reg))
+ Reg = PPC::VSX32 + (Reg - PPC::V0);
+ else if (PPCInstrInfo::isVFRegister(Reg))
+ Reg = PPC::VSX32 + (Reg - PPC::VF0);
+ }
+
+ const char *RegName = getRegisterName(Reg);
// The linux and AIX assembler does not take register prefixes.
if (!isDarwinSyntax())
RegName = stripRegisterPrefix(RegName);