Skip to content

Commit cda23c0

Browse files
committed
[PPC] Fix layering issues between MCTargetDesc and CodeGen
See issue #64166 for more information about the layering issue. The PPCMCTargetDesc library was including CodeGen headers such as PPCInstrInfo.h and calling inline functions in them. This doesn't work in the Bazel build, and is error-prone. If the inline function moves to a cpp file, it will result in linker errors. To address the issue, I moved several inline functions to PPCMCTargetDesc.cpp, and declared them in the PPC namespace in PPCMCTargetDesc.h, which seemed like the most straightforward fix. Differential Revision: https://reviews.llvm.org/D156488
1 parent 1d1f230 commit cda23c0

10 files changed

+288
-267
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
//
1818
//===----------------------------------------------------------------------===//
1919

20-
2120
#include "PPCELFStreamer.h"
2221
#include "PPCFixupKinds.h"
23-
#include "PPCInstrInfo.h"
2422
#include "PPCMCCodeEmitter.h"
23+
#include "PPCMCTargetDesc.h"
2524
#include "llvm/BinaryFormat/ELF.h"
2625
#include "llvm/MC/MCAsmBackend.h"
2726
#include "llvm/MC/MCAssembler.h"

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@
1313
#include "MCTargetDesc/PPCInstPrinter.h"
1414
#include "MCTargetDesc/PPCMCTargetDesc.h"
1515
#include "MCTargetDesc/PPCPredicates.h"
16-
#include "PPCInstrInfo.h"
17-
#include "llvm/CodeGen/TargetOpcodes.h"
1816
#include "llvm/MC/MCExpr.h"
1917
#include "llvm/MC/MCInst.h"
2018
#include "llvm/MC/MCInstrInfo.h"
2119
#include "llvm/MC/MCRegisterInfo.h"
2220
#include "llvm/MC/MCSubtargetInfo.h"
2321
#include "llvm/MC/MCSymbol.h"
22+
#include "llvm/Support/Casting.h"
2423
#include "llvm/Support/CommandLine.h"
2524
#include "llvm/Support/raw_ostream.h"
2625
using namespace llvm;
@@ -646,8 +645,7 @@ void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
646645
if (Op.isReg()) {
647646
unsigned Reg = Op.getReg();
648647
if (!ShowVSRNumsAsVR)
649-
Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()),
650-
Reg, OpNo);
648+
Reg = PPC::getRegNumForOperand(MII.get(MI->getOpcode()), Reg, OpNo);
651649

652650
const char *RegName;
653651
RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg));
@@ -656,7 +654,7 @@ void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
656654
if (showRegistersWithPercentPrefix(RegName))
657655
O << "%";
658656
if (!showRegistersWithPrefix())
659-
RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
657+
RegName = PPC::stripRegisterPrefix(RegName);
660658

661659
O << RegName;
662660
return;

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

Lines changed: 101 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212

1313
#include "PPCMCCodeEmitter.h"
1414
#include "MCTargetDesc/PPCFixupKinds.h"
15-
#include "PPCInstrInfo.h"
15+
#include "PPCMCTargetDesc.h"
1616
#include "llvm/ADT/SmallVector.h"
1717
#include "llvm/ADT/Statistic.h"
18+
#include "llvm/MC/MCExpr.h"
1819
#include "llvm/MC/MCFixup.h"
1920
#include "llvm/MC/MCInstrDesc.h"
2021
#include "llvm/MC/MCRegisterInfo.h"
22+
#include "llvm/Support/Casting.h"
2123
#include "llvm/Support/Endian.h"
2224
#include "llvm/Support/EndianStream.h"
2325
#include "llvm/Support/ErrorHandling.h"
@@ -47,16 +49,108 @@ getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
4749
if (MO.isReg() || MO.isImm())
4850
return getMachineOpValue(MI, MO, Fixups, STI);
4951

50-
const PPCInstrInfo *InstrInfo = static_cast<const PPCInstrInfo *>(&MCII);
51-
unsigned Opcode = MI.getOpcode();
5252
// Add a fixup for the branch target.
5353
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
54-
(InstrInfo->isNoTOCCallInstr(Opcode)
54+
(isNoTOCCallInstr(MI)
5555
? (MCFixupKind)PPC::fixup_ppc_br24_notoc
5656
: (MCFixupKind)PPC::fixup_ppc_br24)));
5757
return 0;
5858
}
5959

60+
/// Check if Opcode corresponds to a call instruction that should be marked
61+
/// with the NOTOC relocation.
62+
bool PPCMCCodeEmitter::isNoTOCCallInstr(const MCInst &MI) const {
63+
unsigned Opcode = MI.getOpcode();
64+
if (!MCII.get(Opcode).isCall())
65+
return false;
66+
67+
switch (Opcode) {
68+
default:
69+
#ifndef NDEBUG
70+
llvm_unreachable("Unknown call opcode");
71+
#endif
72+
return false;
73+
case PPC::BL8_NOTOC:
74+
case PPC::BL8_NOTOC_TLS:
75+
case PPC::BL8_NOTOC_RM:
76+
return true;
77+
#ifndef NDEBUG
78+
case PPC::BL8:
79+
case PPC::BL:
80+
case PPC::BL8_TLS:
81+
case PPC::BL_TLS:
82+
case PPC::BLA8:
83+
case PPC::BLA:
84+
case PPC::BCCL:
85+
case PPC::BCCLA:
86+
case PPC::BCL:
87+
case PPC::BCLn:
88+
case PPC::BL8_NOP:
89+
case PPC::BL_NOP:
90+
case PPC::BL8_NOP_TLS:
91+
case PPC::BLA8_NOP:
92+
case PPC::BCTRL8:
93+
case PPC::BCTRL:
94+
case PPC::BCCCTRL8:
95+
case PPC::BCCCTRL:
96+
case PPC::BCCTRL8:
97+
case PPC::BCCTRL:
98+
case PPC::BCCTRL8n:
99+
case PPC::BCCTRLn:
100+
case PPC::BL8_RM:
101+
case PPC::BLA8_RM:
102+
case PPC::BL8_NOP_RM:
103+
case PPC::BLA8_NOP_RM:
104+
case PPC::BCTRL8_RM:
105+
case PPC::BCTRL8_LDinto_toc:
106+
case PPC::BCTRL8_LDinto_toc_RM:
107+
case PPC::BL8_TLS_:
108+
case PPC::TCRETURNdi8:
109+
case PPC::TCRETURNai8:
110+
case PPC::TCRETURNri8:
111+
case PPC::TAILBCTR8:
112+
case PPC::TAILB8:
113+
case PPC::TAILBA8:
114+
case PPC::BCLalways:
115+
case PPC::BLRL:
116+
case PPC::BCCLRL:
117+
case PPC::BCLRL:
118+
case PPC::BCLRLn:
119+
case PPC::BDZL:
120+
case PPC::BDNZL:
121+
case PPC::BDZLA:
122+
case PPC::BDNZLA:
123+
case PPC::BDZLp:
124+
case PPC::BDNZLp:
125+
case PPC::BDZLAp:
126+
case PPC::BDNZLAp:
127+
case PPC::BDZLm:
128+
case PPC::BDNZLm:
129+
case PPC::BDZLAm:
130+
case PPC::BDNZLAm:
131+
case PPC::BDZLRL:
132+
case PPC::BDNZLRL:
133+
case PPC::BDZLRLp:
134+
case PPC::BDNZLRLp:
135+
case PPC::BDZLRLm:
136+
case PPC::BDNZLRLm:
137+
case PPC::BL_RM:
138+
case PPC::BLA_RM:
139+
case PPC::BL_NOP_RM:
140+
case PPC::BCTRL_RM:
141+
case PPC::TCRETURNdi:
142+
case PPC::TCRETURNai:
143+
case PPC::TCRETURNri:
144+
case PPC::BCTRL_LWZinto_toc:
145+
case PPC::BCTRL_LWZinto_toc_RM:
146+
case PPC::TAILBCTR:
147+
case PPC::TAILB:
148+
case PPC::TAILBA:
149+
return false;
150+
#endif
151+
}
152+
}
153+
60154
unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
61155
SmallVectorImpl<MCFixup> &Fixups,
62156
const MCSubtargetInfo &STI) const {
@@ -372,7 +466,7 @@ get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
372466
}
373467

374468
// Get the index for this operand in this instruction. This is needed for
375-
// computing the register number in PPCInstrInfo::getRegNumForOperand() for
469+
// computing the register number in PPC::getRegNumForOperand() for
376470
// any instructions that use a different numbering scheme for registers in
377471
// different operands.
378472
static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) {
@@ -397,8 +491,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
397491
MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
398492
unsigned OpNo = getOpIdxForMO(MI, MO);
399493
unsigned Reg =
400-
PPCInstrInfo::getRegNumForOperand(MCII.get(MI.getOpcode()),
401-
MO.getReg(), OpNo);
494+
PPC::getRegNumForOperand(MCII.get(MI.getOpcode()), MO.getReg(), OpNo);
402495
return CTX.getRegisterInfo()->getEncodingValue(Reg);
403496
}
404497

@@ -443,9 +536,7 @@ unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst &MI) const {
443536
}
444537

445538
bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst &MI) const {
446-
unsigned Opcode = MI.getOpcode();
447-
const PPCInstrInfo *InstrInfo = static_cast<const PPCInstrInfo*>(&MCII);
448-
return InstrInfo->isPrefixed(Opcode);
539+
return MCII.get(MI.getOpcode()).TSFlags & PPCII::Prefixed;
449540
}
450541

451542
#include "PPCGenMCCodeEmitter.inc"

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ class PPCMCCodeEmitter : public MCCodeEmitter {
121121

122122
// Is this instruction a prefixed instruction.
123123
bool isPrefixedInstruction(const MCInst &MI) const;
124+
125+
/// Check if Opcode corresponds to a call instruction that should be marked
126+
/// with the NOTOC relocation.
127+
bool isNoTOCCallInstr(const MCInst &MI) const;
124128
};
125129

126130
} // namespace llvm

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

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,90 @@ using namespace llvm;
5757
#define GET_REGINFO_MC_DESC
5858
#include "PPCGenRegisterInfo.inc"
5959

60+
/// stripRegisterPrefix - This method strips the character prefix from a
61+
/// register name so that only the number is left. Used by for linux asm.
62+
const char *PPC::stripRegisterPrefix(const char *RegName) {
63+
switch (RegName[0]) {
64+
case 'a':
65+
if (RegName[1] == 'c' && RegName[2] == 'c')
66+
return RegName + 3;
67+
break;
68+
case 'f':
69+
if (RegName[1] == 'p')
70+
return RegName + 2;
71+
[[fallthrough]];
72+
case 'r':
73+
case 'v':
74+
if (RegName[1] == 's') {
75+
if (RegName[2] == 'p')
76+
return RegName + 3;
77+
return RegName + 2;
78+
}
79+
return RegName + 1;
80+
case 'c':
81+
if (RegName[1] == 'r')
82+
return RegName + 2;
83+
break;
84+
case 'w':
85+
// For wacc and wacc_hi
86+
if (RegName[1] == 'a' && RegName[2] == 'c' && RegName[3] == 'c') {
87+
if (RegName[4] == '_')
88+
return RegName + 7;
89+
else
90+
return RegName + 4;
91+
}
92+
break;
93+
case 'd':
94+
// For dmr, dmrp, dmrrow, dmrrowp
95+
if (RegName[1] == 'm' && RegName[2] == 'r') {
96+
if (RegName[3] == 'r' && RegName[4] == 'o' && RegName[5] == 'w' &&
97+
RegName[6] == 'p')
98+
return RegName + 7;
99+
else if (RegName[3] == 'r' && RegName[4] == 'o' && RegName[5] == 'w')
100+
return RegName + 6;
101+
else if (RegName[3] == 'p')
102+
return RegName + 4;
103+
else
104+
return RegName + 3;
105+
}
106+
break;
107+
}
108+
109+
return RegName;
110+
}
111+
112+
/// getRegNumForOperand - some operands use different numbering schemes
113+
/// for the same registers. For example, a VSX instruction may have any of
114+
/// vs0-vs63 allocated whereas an Altivec instruction could only have
115+
/// vs32-vs63 allocated (numbered as v0-v31). This function returns the actual
116+
/// register number needed for the opcode/operand number combination.
117+
/// The operand number argument will be useful when we need to extend this
118+
/// to instructions that use both Altivec and VSX numbering (for different
119+
/// operands).
120+
unsigned PPC::getRegNumForOperand(const MCInstrDesc &Desc, unsigned Reg,
121+
unsigned OpNo) {
122+
int16_t regClass = Desc.operands()[OpNo].RegClass;
123+
switch (regClass) {
124+
// We store F0-F31, VF0-VF31 in MCOperand and it should be F0-F31,
125+
// VSX32-VSX63 during encoding/disassembling
126+
case PPC::VSSRCRegClassID:
127+
case PPC::VSFRCRegClassID:
128+
if (PPC::isVFRegister(Reg))
129+
return PPC::VSX32 + (Reg - PPC::VF0);
130+
break;
131+
// We store VSL0-VSL31, V0-V31 in MCOperand and it should be VSL0-VSL31,
132+
// VSX32-VSX63 during encoding/disassembling
133+
case PPC::VSRCRegClassID:
134+
if (PPC::isVRRegister(Reg))
135+
return PPC::VSX32 + (Reg - PPC::V0);
136+
break;
137+
// Other RegClass doesn't need mapping
138+
default:
139+
break;
140+
}
141+
return Reg;
142+
}
143+
60144
PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
61145

62146
// Pin the vtable to this file.

0 commit comments

Comments
 (0)