Index: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -499,43 +499,14 @@ return TT.isOSDarwin() || FullRegNamesWithPercent || FullRegNames; } -/// stripRegisterPrefix - This method strips the character prefix from a -/// register name so that only the number is left. -static const char *stripRegisterPrefix(const char *RegName) { - switch (RegName[0]) { - case 'r': - case 'f': - case 'q': // for QPX - case 'v': - if (RegName[1] == 's') - return RegName + 2; - return RegName + 1; - case 'c': if (RegName[1] == 'r') return RegName + 2; - } - - return RegName; -} - void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) { 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); - } + if (!ShowVSRNumsAsVR) + Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()), + Reg, OpNo); const char *RegName; RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg)); @@ -544,7 +515,7 @@ if (showRegistersWithPercentPrefix(RegName)) O << "%"; if (!showRegistersWithPrefix()) - RegName = stripRegisterPrefix(RegName); + RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); O << RegName; return; Index: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -360,6 +360,20 @@ return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); } +// Get the index for this operand in this instruction. This is needed for +// computing the register number in PPCInstrInfo::getRegNumForOperand() for +// any instructions that use a different numbering scheme for registers in +// different operands. +static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) { + for (unsigned i = 0; i < MI.getNumOperands(); i++) { + const MCOperand &Op = MI.getOperand(i); + if (&Op == &MO) + return i; + } + llvm_unreachable("This operand is not part of this instruction"); + return ~0U; // Silence any warnings about no return. +} + unsigned PPCMCCodeEmitter:: getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl &Fixups, @@ -370,14 +384,11 @@ assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 && MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) || MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); - unsigned Reg = MO.getReg(); - unsigned Encode = CTX.getRegisterInfo()->getEncodingValue(Reg); - - if ((MCII.get(MI.getOpcode()).TSFlags & PPCII::UseVSXReg)) - if (PPCInstrInfo::isVRRegister(Reg)) - Encode += 32; - - return Encode; + unsigned OpNo = getOpIdxForMO(MI, MO); + unsigned Reg = + PPCInstrInfo::getRegNumForOperand(MCII.get(MI.getOpcode()), + MO.getReg(), OpNo); + return CTX.getRegisterInfo()->getEncodingValue(Reg); } assert(MO.isImm() && Index: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -158,23 +158,6 @@ } // end anonymous namespace -/// 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) { - switch (RegName[0]) { - case 'r': - case 'f': - case 'q': // for QPX - case 'v': - if (RegName[1] == 's') - return RegName + 2; - return RegName + 1; - case 'c': if (RegName[1] == 'r') return RegName + 2; - } - - return RegName; -} - void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { const DataLayout &DL = getDataLayout(); @@ -182,27 +165,15 @@ switch (MO.getType()) { case MachineOperand::MO_Register: { - unsigned Reg = MO.getReg(); + unsigned Reg = PPCInstrInfo::getRegNumForOperand(MI->getDesc(), + MO.getReg(), OpNo); - // 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 PPCInstPrinter::printOperand) - if (MI->getDesc().TSFlags & PPCII::UseVSXReg) { - if (PPCInstrInfo::isVRRegister(Reg)) - Reg = PPC::VSX32 + (Reg - PPC::V0); - else if (PPCInstrInfo::isVFRegister(Reg)) - Reg = PPC::VSX32 + (Reg - PPC::VF0); - } const char *RegName = PPCInstPrinter::getRegisterName(Reg); // Linux assembler (Others?) does not take register mnemonics. // FIXME - What about special registers used in mfspr/mtspr? if (!Subtarget->isDarwin()) - RegName = stripRegisterPrefix(RegName); + RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); O << RegName; return; } @@ -291,7 +262,7 @@ Reg = PPC::VSX32 + (Reg - PPC::VF0); const char *RegName; RegName = PPCInstPrinter::getRegisterName(Reg); - RegName = stripRegisterPrefix(RegName); + RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); O << RegName; return false; } @@ -318,7 +289,7 @@ { const char *RegName = "r0"; if (!Subtarget->isDarwin()) - RegName = stripRegisterPrefix(RegName); + RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); O << RegName << ", "; printOperand(MI, OpNo, O); return false; Index: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h @@ -405,6 +405,25 @@ void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const; bool instrHasImmForm(const MachineInstr &MI, ImmInstrInfo &III) const; + + /// getRegNumForOperand - some operands use different numbering schemes + /// for the same registers. For example, a VSX instruction may have any of + /// vs0-vs63 allocated whereas an Altivec instruction could only have + /// vs32-vs63 allocated (numbered as v0-v31). This function returns the actual + /// register number needed for the opcode/operand number combination. + /// The operand number argument will be useful when we need to extend this + /// to instructions that use both Altivec and VSX numbering (for different + /// operands). + static unsigned getRegNumForOperand(const MCInstrDesc &Desc, unsigned Reg, + unsigned OpNo) { + if (Desc.TSFlags & PPCII::UseVSXReg) { + if (isVRRegister(Reg)) + Reg = PPC::VSX32 + (Reg - PPC::V0); + else if (isVFRegister(Reg)) + Reg = PPC::VSX32 + (Reg - PPC::VF0); + } + return Reg; + } }; } Index: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h @@ -141,6 +141,23 @@ // Base pointer (stack realignment) support. unsigned getBaseRegister(const MachineFunction &MF) const; bool hasBasePointer(const MachineFunction &MF) const; + + /// 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) { + switch (RegName[0]) { + case 'r': + case 'f': + case 'q': // for QPX + case 'v': + if (RegName[1] == 's') + return RegName + 2; + return RegName + 1; + case 'c': if (RegName[1] == 'r') return RegName + 2; + } + + return RegName; + } }; } // end namespace llvm Index: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td @@ -85,6 +85,12 @@ let SubRegIndices = [sub_64]; } +// VSXReg - One of the VSX registers in the range vs32-vs63 with numbering +// and encoding to match. +class VSXReg num, string n> : PPCReg { + let HWEncoding{5-0} = num; +} + // CR - One of the 8 4-bit condition registers class CR num, string n, list subregs> : PPCReg { let HWEncoding{2-0} = num; @@ -148,7 +154,7 @@ // Dummy VSX registers, this defines string: "vs32"-"vs63", and is only used for // asm printing. foreach Index = 32-63 in { - def VSX#Index : PPCReg<"vs"#Index>; + def VSX#Index : VSXReg; } // The reprsentation of r0 when treated as the constant 0.