//===-------------- PPCVSXCopy.cpp - VSX Copy Legalization ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// A pass which deals with the complexity of generating legal VSX register
// copies to/from register classes which partially overlap with the VSX
// register file.
//
//===----------------------------------------------------------------------===//

#include "PPCInstrInfo.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "PPC.h"
#include "PPCHazardRecognizers.h"
#include "PPCInstrBuilder.h"
#include "PPCMachineFunctionInfo.h"
#include "PPCTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "ppc-vsx-copy"

namespace llvm {
  void initializePPCVSXCopyPass(PassRegistry&);
}

namespace {
  // PPCVSXCopy pass - For copies between VSX registers and non-VSX registers
  // (Altivec and scalar floating-point registers), we need to transform the
  // copies into subregister copies with other restrictions.
  struct PPCVSXCopy : public MachineFunctionPass {
    static char ID;
    PPCVSXCopy() : MachineFunctionPass(ID) {
      initializePPCVSXCopyPass(*PassRegistry::getPassRegistry());
    }

    const TargetInstrInfo *TII;

    bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
                      MachineRegisterInfo &MRI) {
      if (TargetRegisterInfo::isVirtualRegister(Reg)) {
        return RC->hasSubClassEq(MRI.getRegClass(Reg));
      } else if (RC->contains(Reg)) {
        return true;
      }

      return false;
    }

    bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
      return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
    }

    bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
      return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
    }

    bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
      return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
    }

    bool IsVSFReg(unsigned Reg, MachineRegisterInfo &MRI) {
      return IsRegInClass(Reg, &PPC::VSFRCRegClass, MRI);
    }

    bool IsVSSReg(unsigned Reg, MachineRegisterInfo &MRI) {
      return IsRegInClass(Reg, &PPC::VSSRCRegClass, MRI);
    }

protected:
    bool processBlock(MachineBasicBlock &MBB) {
      bool Changed = false;

      MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
      for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
           I != IE; ++I) {
        MachineInstr *MI = I;
        if (!MI->isFullCopy())
          continue;

        MachineOperand &DstMO = MI->getOperand(0);
        MachineOperand &SrcMO = MI->getOperand(1);

        if ( IsVSReg(DstMO.getReg(), MRI) &&
            !IsVSReg(SrcMO.getReg(), MRI)) {
          // This is a copy *to* a VSX register from a non-VSX register.
          Changed = true;

          const TargetRegisterClass *SrcRC =
            IsVRReg(SrcMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
                                           &PPC::VSLRCRegClass;
          assert((IsF8Reg(SrcMO.getReg(), MRI) ||
                  IsVRReg(SrcMO.getReg(), MRI) ||
                  IsVSSReg(SrcMO.getReg(), MRI) ||
                  IsVSFReg(SrcMO.getReg(), MRI)) &&
                 "Unknown source for a VSX copy");

          unsigned NewVReg = MRI.createVirtualRegister(SrcRC);
          BuildMI(MBB, MI, MI->getDebugLoc(),
                  TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
            .addImm(1) // add 1, not 0, because there is no implicit clearing
                       // of the high bits.
            .addOperand(SrcMO)
            .addImm(IsVRReg(SrcMO.getReg(), MRI) ? PPC::sub_128 :
                                                   PPC::sub_64);

          // The source of the original copy is now the new virtual register.
          SrcMO.setReg(NewVReg);
        } else if (!IsVSReg(DstMO.getReg(), MRI) &&
                    IsVSReg(SrcMO.getReg(), MRI)) {
          // This is a copy *from* a VSX register to a non-VSX register.
          Changed = true;

          const TargetRegisterClass *DstRC =
            IsVRReg(DstMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
                                           &PPC::VSLRCRegClass;
          assert((IsF8Reg(DstMO.getReg(), MRI) ||
                  IsVSFReg(DstMO.getReg(), MRI) ||
                  IsVSSReg(DstMO.getReg(), MRI) ||
                  IsVRReg(DstMO.getReg(), MRI)) &&
                 "Unknown destination for a VSX copy");

          // Copy the VSX value into a new VSX register of the correct subclass.
          unsigned NewVReg = MRI.createVirtualRegister(DstRC);
          BuildMI(MBB, MI, MI->getDebugLoc(),
                  TII->get(TargetOpcode::COPY), NewVReg)
            .addOperand(SrcMO);

          // Transform the original copy into a subregister extraction copy.
          SrcMO.setReg(NewVReg);
          SrcMO.setSubReg(IsVRReg(DstMO.getReg(), MRI) ? PPC::sub_128 :
                                                         PPC::sub_64);
        }
      }

      return Changed;
    }

public:
    bool runOnMachineFunction(MachineFunction &MF) override {
      // If we don't have VSX on the subtarget, don't do anything.
      const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>();
      if (!STI.hasVSX())
        return false;
      TII = STI.getInstrInfo();

      bool Changed = false;

      for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
        MachineBasicBlock &B = *I++;
        if (processBlock(B))
          Changed = true;
      }

      return Changed;
    }

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      MachineFunctionPass::getAnalysisUsage(AU);
    }
  };
}

INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
                "PowerPC VSX Copy Legalization", false, false)

char PPCVSXCopy::ID = 0;
FunctionPass*
llvm::createPPCVSXCopyPass() { return new PPCVSXCopy(); }

