Skip to content

Commit a590967

Browse files
committed
[PowerPC] [NFC] Refactor code for printing register operands
We have an unfortunate situation in our back end where we have to keep pairs of functions synchronized. Needless to say that this is not an ideal situation as it is very difficult to enforce. Even without bugs, it's annoying to have to do the same thing in two places. This patch just refactors the code so that the two pairs of those functions that pertain to printing register operands are unified: - stripRegisterPrefix() - this just removes the letter prefixes from registers for the InstrPrinter and AsmPrinter. This patch provides this as a static member of PPCRegisterInfo - Handling of PPCII::UseVSXReg - there are 3 places where we do something special for instructions with that flag set. Each of those places does its own checking of this flag and implements code customization. Any changes to how we print/encode VSX/VMX registers require modifying all 3 places. This patch unifies this into a static function in PPCInstrInfo that returns the register number adjusted as needed. Differential revision: https://reviews.llvm.org/D52467 llvm-svn: 343195
1 parent 7e4f154 commit a590967

File tree

6 files changed

+72
-77
lines changed

6 files changed

+72
-77
lines changed

llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -499,43 +499,14 @@ bool PPCInstPrinter::showRegistersWithPrefix() const {
499499
return TT.isOSDarwin() || FullRegNamesWithPercent || FullRegNames;
500500
}
501501

502-
/// stripRegisterPrefix - This method strips the character prefix from a
503-
/// register name so that only the number is left.
504-
static const char *stripRegisterPrefix(const char *RegName) {
505-
switch (RegName[0]) {
506-
case 'r':
507-
case 'f':
508-
case 'q': // for QPX
509-
case 'v':
510-
if (RegName[1] == 's')
511-
return RegName + 2;
512-
return RegName + 1;
513-
case 'c': if (RegName[1] == 'r') return RegName + 2;
514-
}
515-
516-
return RegName;
517-
}
518-
519502
void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
520503
raw_ostream &O) {
521504
const MCOperand &Op = MI->getOperand(OpNo);
522505
if (Op.isReg()) {
523506
unsigned Reg = Op.getReg();
524-
525-
// There are VSX instructions that use VSX register numbering (vs0 - vs63)
526-
// as well as those that use VMX register numbering (v0 - v31 which
527-
// correspond to vs32 - vs63). If we have an instruction that uses VSX
528-
// numbering, we need to convert the VMX registers to VSX registers.
529-
// Namely, we print 32-63 when the instruction operates on one of the
530-
// VMX registers.
531-
// (Please synchronize with PPCAsmPrinter::printOperand)
532-
if ((MII.get(MI->getOpcode()).TSFlags & PPCII::UseVSXReg) &&
533-
!ShowVSRNumsAsVR) {
534-
if (PPCInstrInfo::isVRRegister(Reg))
535-
Reg = PPC::VSX32 + (Reg - PPC::V0);
536-
else if (PPCInstrInfo::isVFRegister(Reg))
537-
Reg = PPC::VSX32 + (Reg - PPC::VF0);
538-
}
507+
if (!ShowVSRNumsAsVR)
508+
Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()),
509+
Reg, OpNo);
539510

540511
const char *RegName;
541512
RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg));
@@ -544,7 +515,7 @@ void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
544515
if (showRegistersWithPercentPrefix(RegName))
545516
O << "%";
546517
if (!showRegistersWithPrefix())
547-
RegName = stripRegisterPrefix(RegName);
518+
RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
548519

549520
O << RegName;
550521
return;

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,20 @@ get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
360360
return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
361361
}
362362

363+
// Get the index for this operand in this instruction. This is needed for
364+
// computing the register number in PPCInstrInfo::getRegNumForOperand() for
365+
// any instructions that use a different numbering scheme for registers in
366+
// different operands.
367+
static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) {
368+
for (unsigned i = 0; i < MI.getNumOperands(); i++) {
369+
const MCOperand &Op = MI.getOperand(i);
370+
if (&Op == &MO)
371+
return i;
372+
}
373+
llvm_unreachable("This operand is not part of this instruction");
374+
return ~0U; // Silence any warnings about no return.
375+
}
376+
363377
unsigned PPCMCCodeEmitter::
364378
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
365379
SmallVectorImpl<MCFixup> &Fixups,
@@ -370,14 +384,11 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
370384
assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
371385
MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
372386
MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
373-
unsigned Reg = MO.getReg();
374-
unsigned Encode = CTX.getRegisterInfo()->getEncodingValue(Reg);
375-
376-
if ((MCII.get(MI.getOpcode()).TSFlags & PPCII::UseVSXReg))
377-
if (PPCInstrInfo::isVRRegister(Reg))
378-
Encode += 32;
379-
380-
return Encode;
387+
unsigned OpNo = getOpIdxForMO(MI, MO);
388+
unsigned Reg =
389+
PPCInstrInfo::getRegNumForOperand(MCII.get(MI.getOpcode()),
390+
MO.getReg(), OpNo);
391+
return CTX.getRegisterInfo()->getEncodingValue(Reg);
381392
}
382393

383394
assert(MO.isImm() &&

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -158,51 +158,22 @@ class PPCAsmPrinter : public AsmPrinter {
158158

159159
} // end anonymous namespace
160160

161-
/// stripRegisterPrefix - This method strips the character prefix from a
162-
/// register name so that only the number is left. Used by for linux asm.
163-
static const char *stripRegisterPrefix(const char *RegName) {
164-
switch (RegName[0]) {
165-
case 'r':
166-
case 'f':
167-
case 'q': // for QPX
168-
case 'v':
169-
if (RegName[1] == 's')
170-
return RegName + 2;
171-
return RegName + 1;
172-
case 'c': if (RegName[1] == 'r') return RegName + 2;
173-
}
174-
175-
return RegName;
176-
}
177-
178161
void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
179162
raw_ostream &O) {
180163
const DataLayout &DL = getDataLayout();
181164
const MachineOperand &MO = MI->getOperand(OpNo);
182165

183166
switch (MO.getType()) {
184167
case MachineOperand::MO_Register: {
185-
unsigned Reg = MO.getReg();
186-
187-
// There are VSX instructions that use VSX register numbering (vs0 - vs63)
188-
// as well as those that use VMX register numbering (v0 - v31 which
189-
// correspond to vs32 - vs63). If we have an instruction that uses VSX
190-
// numbering, we need to convert the VMX registers to VSX registers.
191-
// Namely, we print 32-63 when the instruction operates on one of the
192-
// VMX registers.
193-
// (Please synchronize with PPCInstPrinter::printOperand)
194-
if (MI->getDesc().TSFlags & PPCII::UseVSXReg) {
195-
if (PPCInstrInfo::isVRRegister(Reg))
196-
Reg = PPC::VSX32 + (Reg - PPC::V0);
197-
else if (PPCInstrInfo::isVFRegister(Reg))
198-
Reg = PPC::VSX32 + (Reg - PPC::VF0);
199-
}
168+
unsigned Reg = PPCInstrInfo::getRegNumForOperand(MI->getDesc(),
169+
MO.getReg(), OpNo);
170+
200171
const char *RegName = PPCInstPrinter::getRegisterName(Reg);
201172

202173
// Linux assembler (Others?) does not take register mnemonics.
203174
// FIXME - What about special registers used in mfspr/mtspr?
204175
if (!Subtarget->isDarwin())
205-
RegName = stripRegisterPrefix(RegName);
176+
RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
206177
O << RegName;
207178
return;
208179
}
@@ -291,7 +262,7 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
291262
Reg = PPC::VSX32 + (Reg - PPC::VF0);
292263
const char *RegName;
293264
RegName = PPCInstPrinter::getRegisterName(Reg);
294-
RegName = stripRegisterPrefix(RegName);
265+
RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
295266
O << RegName;
296267
return false;
297268
}
@@ -318,7 +289,7 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
318289
{
319290
const char *RegName = "r0";
320291
if (!Subtarget->isDarwin())
321-
RegName = stripRegisterPrefix(RegName);
292+
RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
322293
O << RegName << ", ";
323294
printOperand(MI, OpNo, O);
324295
return false;

llvm/lib/Target/PowerPC/PPCInstrInfo.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,25 @@ class PPCInstrInfo : public PPCGenInstrInfo {
405405
void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const;
406406

407407
bool instrHasImmForm(const MachineInstr &MI, ImmInstrInfo &III) const;
408+
409+
/// getRegNumForOperand - some operands use different numbering schemes
410+
/// for the same registers. For example, a VSX instruction may have any of
411+
/// vs0-vs63 allocated whereas an Altivec instruction could only have
412+
/// vs32-vs63 allocated (numbered as v0-v31). This function returns the actual
413+
/// register number needed for the opcode/operand number combination.
414+
/// The operand number argument will be useful when we need to extend this
415+
/// to instructions that use both Altivec and VSX numbering (for different
416+
/// operands).
417+
static unsigned getRegNumForOperand(const MCInstrDesc &Desc, unsigned Reg,
418+
unsigned OpNo) {
419+
if (Desc.TSFlags & PPCII::UseVSXReg) {
420+
if (isVRRegister(Reg))
421+
Reg = PPC::VSX32 + (Reg - PPC::V0);
422+
else if (isVFRegister(Reg))
423+
Reg = PPC::VSX32 + (Reg - PPC::VF0);
424+
}
425+
return Reg;
426+
}
408427
};
409428

410429
}

llvm/lib/Target/PowerPC/PPCRegisterInfo.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,23 @@ class PPCRegisterInfo : public PPCGenRegisterInfo {
141141
// Base pointer (stack realignment) support.
142142
unsigned getBaseRegister(const MachineFunction &MF) const;
143143
bool hasBasePointer(const MachineFunction &MF) const;
144+
145+
/// stripRegisterPrefix - This method strips the character prefix from a
146+
/// register name so that only the number is left. Used by for linux asm.
147+
static const char *stripRegisterPrefix(const char *RegName) {
148+
switch (RegName[0]) {
149+
case 'r':
150+
case 'f':
151+
case 'q': // for QPX
152+
case 'v':
153+
if (RegName[1] == 's')
154+
return RegName + 2;
155+
return RegName + 1;
156+
case 'c': if (RegName[1] == 'r') return RegName + 2;
157+
}
158+
159+
return RegName;
160+
}
144161
};
145162

146163
} // end namespace llvm

llvm/lib/Target/PowerPC/PPCRegisterInfo.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ class VSRL<FPR SubReg, string n> : PPCReg<n> {
8585
let SubRegIndices = [sub_64];
8686
}
8787

88+
// VSXReg - One of the VSX registers in the range vs32-vs63 with numbering
89+
// and encoding to match.
90+
class VSXReg<bits<6> num, string n> : PPCReg<n> {
91+
let HWEncoding{5-0} = num;
92+
}
93+
8894
// CR - One of the 8 4-bit condition registers
8995
class CR<bits<3> num, string n, list<Register> subregs> : PPCReg<n> {
9096
let HWEncoding{2-0} = num;
@@ -148,7 +154,7 @@ foreach Index = 0-31 in {
148154
// Dummy VSX registers, this defines string: "vs32"-"vs63", and is only used for
149155
// asm printing.
150156
foreach Index = 32-63 in {
151-
def VSX#Index : PPCReg<"vs"#Index>;
157+
def VSX#Index : VSXReg<Index, "vs"#Index>;
152158
}
153159

154160
// The reprsentation of r0 when treated as the constant 0.

0 commit comments

Comments
 (0)