reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
//===-- PPCRegisterInfo.h - PowerPC Register Information Impl ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetRegisterInfo
// class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H
#define LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H

#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "llvm/ADT/DenseMap.h"

#define GET_REGINFO_HEADER
#include "PPCGenRegisterInfo.inc"

namespace llvm {
class PPCTargetMachine;

inline static unsigned getCRFromCRBit(unsigned SrcReg) {
  unsigned Reg = 0;
  if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||
      SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)
    Reg = PPC::CR0;
  else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||
           SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)
    Reg = PPC::CR1;
  else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||
           SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)
    Reg = PPC::CR2;
  else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||
           SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)
    Reg = PPC::CR3;
  else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||
           SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)
    Reg = PPC::CR4;
  else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||
           SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)
    Reg = PPC::CR5;
  else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||
           SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)
    Reg = PPC::CR6;
  else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||
           SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)
    Reg = PPC::CR7;

  assert(Reg != 0 && "Invalid CR bit register");
  return Reg;
}

class PPCRegisterInfo : public PPCGenRegisterInfo {
  DenseMap<unsigned, unsigned> ImmToIdxMap;
  const PPCTargetMachine &TM;

public:
  PPCRegisterInfo(const PPCTargetMachine &TM);

  /// getMappedIdxOpcForImmOpc - Return the mapped index form load/store opcode
  /// for a given imm form load/store opcode \p ImmFormOpcode.
  /// FIXME: move this to PPCInstrInfo class.
  unsigned getMappedIdxOpcForImmOpc(unsigned ImmOpcode) const {
    if (!ImmToIdxMap.count(ImmOpcode))
      return PPC::INSTRUCTION_LIST_END;
    return ImmToIdxMap.find(ImmOpcode)->second;
  }

  /// getPointerRegClass - Return the register class to use to hold pointers.
  /// This is used for addressing modes.
  const TargetRegisterClass *
  getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override;

  unsigned getRegPressureLimit(const TargetRegisterClass *RC,
                               MachineFunction &MF) const override;

  const TargetRegisterClass *
  getLargestLegalSuperClass(const TargetRegisterClass *RC,
                            const MachineFunction &MF) const override;

  /// Code Generation virtual methods...
  const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
  const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
  const uint32_t *getCallPreservedMask(const MachineFunction &MF,
                                       CallingConv::ID CC) const override;
  const uint32_t *getNoPreservedMask() const override;

  void adjustStackMapLiveOutMask(uint32_t *Mask) const override;

  BitVector getReservedRegs(const MachineFunction &MF) const override;
  bool isCallerPreservedPhysReg(unsigned PhysReg, const MachineFunction &MF) const override;

  /// We require the register scavenger.
  bool requiresRegisterScavenging(const MachineFunction &MF) const override {
    return true;
  }

  bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;

  bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override {
    return true;
  }

  bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override {
    return true;
  }

  void lowerDynamicAlloc(MachineBasicBlock::iterator II) const;
  void lowerDynamicAreaOffset(MachineBasicBlock::iterator II) const;
  void lowerCRSpilling(MachineBasicBlock::iterator II,
                       unsigned FrameIndex) const;
  void lowerCRRestore(MachineBasicBlock::iterator II,
                      unsigned FrameIndex) const;
  void lowerCRBitSpilling(MachineBasicBlock::iterator II,
                          unsigned FrameIndex) const;
  void lowerCRBitRestore(MachineBasicBlock::iterator II,
                         unsigned FrameIndex) const;
  void lowerVRSAVESpilling(MachineBasicBlock::iterator II,
                           unsigned FrameIndex) const;
  void lowerVRSAVERestore(MachineBasicBlock::iterator II,
                          unsigned FrameIndex) const;

  bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
                            int &FrameIdx) const override;
  void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
                           unsigned FIOperandNum,
                           RegScavenger *RS = nullptr) const override;

  // Support for virtual base registers.
  bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
  void materializeFrameBaseRegister(MachineBasicBlock *MBB,
                                    unsigned BaseReg, int FrameIdx,
                                    int64_t Offset) const override;
  void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
                         int64_t Offset) const override;
  bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
                          int64_t Offset) const override;

  // Debug information queries.
  Register getFrameRegister(const MachineFunction &MF) const override;

  // Base pointer (stack realignment) support.
  Register 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

#endif