aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp87
1 files changed, 86 insertions, 1 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index 271f7ab757e1..a804dd823daa 100644
--- a/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -57,6 +57,90 @@ using namespace llvm;
#define GET_REGINFO_MC_DESC
#include "PPCGenRegisterInfo.inc"
+/// stripRegisterPrefix - This method strips the character prefix from a
+/// register name so that only the number is left. Used by for linux asm.
+const char *PPC::stripRegisterPrefix(const char *RegName) {
+ switch (RegName[0]) {
+ case 'a':
+ if (RegName[1] == 'c' && RegName[2] == 'c')
+ return RegName + 3;
+ break;
+ case 'f':
+ if (RegName[1] == 'p')
+ return RegName + 2;
+ [[fallthrough]];
+ case 'r':
+ case 'v':
+ if (RegName[1] == 's') {
+ if (RegName[2] == 'p')
+ return RegName + 3;
+ return RegName + 2;
+ }
+ return RegName + 1;
+ case 'c':
+ if (RegName[1] == 'r')
+ return RegName + 2;
+ break;
+ case 'w':
+ // For wacc and wacc_hi
+ if (RegName[1] == 'a' && RegName[2] == 'c' && RegName[3] == 'c') {
+ if (RegName[4] == '_')
+ return RegName + 7;
+ else
+ return RegName + 4;
+ }
+ break;
+ case 'd':
+ // For dmr, dmrp, dmrrow, dmrrowp
+ if (RegName[1] == 'm' && RegName[2] == 'r') {
+ if (RegName[3] == 'r' && RegName[4] == 'o' && RegName[5] == 'w' &&
+ RegName[6] == 'p')
+ return RegName + 7;
+ else if (RegName[3] == 'r' && RegName[4] == 'o' && RegName[5] == 'w')
+ return RegName + 6;
+ else if (RegName[3] == 'p')
+ return RegName + 4;
+ else
+ return RegName + 3;
+ }
+ break;
+ }
+
+ return RegName;
+}
+
+/// 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).
+unsigned PPC::getRegNumForOperand(const MCInstrDesc &Desc, unsigned Reg,
+ unsigned OpNo) {
+ int16_t regClass = Desc.operands()[OpNo].RegClass;
+ switch (regClass) {
+ // We store F0-F31, VF0-VF31 in MCOperand and it should be F0-F31,
+ // VSX32-VSX63 during encoding/disassembling
+ case PPC::VSSRCRegClassID:
+ case PPC::VSFRCRegClassID:
+ if (PPC::isVFRegister(Reg))
+ return PPC::VSX32 + (Reg - PPC::VF0);
+ break;
+ // We store VSL0-VSL31, V0-V31 in MCOperand and it should be VSL0-VSL31,
+ // VSX32-VSX63 during encoding/disassembling
+ case PPC::VSRCRegClassID:
+ if (PPC::isVRRegister(Reg))
+ return PPC::VSX32 + (Reg - PPC::V0);
+ break;
+ // Other RegClass doesn't need mapping
+ default:
+ break;
+ }
+ return Reg;
+}
+
PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
// Pin the vtable to this file.
@@ -148,9 +232,10 @@ public:
cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
->getQualNameSymbol();
// On AIX, we have a region handle (symbol@m) and the variable offset
- // (symbol@{gd|le}) for TLS variables, depending on the TLS model.
+ // (symbol@{gd|ie|le}) for TLS variables, depending on the TLS model.
if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD ||
Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
+ Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE ||
Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE)
OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
<< MCSymbolRefExpr::getVariantKindName(Kind) << '\n';