//===-- SystemZSubtarget.h - SystemZ subtarget information -----*- 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 declares the SystemZ specific subclass of TargetSubtargetInfo.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZSUBTARGET_H
#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZSUBTARGET_H

#include "SystemZFrameLowering.h"
#include "SystemZISelLowering.h"
#include "SystemZInstrInfo.h"
#include "SystemZRegisterInfo.h"
#include "SystemZSelectionDAGInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/TargetParser/Triple.h"
#include <string>

#define GET_SUBTARGETINFO_HEADER
#include "SystemZGenSubtargetInfo.inc"

namespace llvm {
class GlobalValue;
class StringRef;

class SystemZSubtarget : public SystemZGenSubtargetInfo {
  virtual void anchor();
protected:
// Bool members corresponding to the SubtargetFeatures defined in tablegen.
#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
  bool ATTRIBUTE = DEFAULT;
#include "SystemZGenSubtargetInfo.inc"

private:
  Triple TargetTriple;
  std::unique_ptr<SystemZCallingConventionRegisters> SpecialRegisters;
  SystemZInstrInfo InstrInfo;
  SystemZTargetLowering TLInfo;
  SystemZSelectionDAGInfo TSInfo;
  std::unique_ptr<const SystemZFrameLowering> FrameLowering;

  SystemZSubtarget &initializeSubtargetDependencies(StringRef CPU,
                                                    StringRef TuneCPU,
                                                    StringRef FS);
  SystemZCallingConventionRegisters *initializeSpecialRegisters();

public:
  SystemZSubtarget(const Triple &TT, const std::string &CPU,
                   const std::string &TuneCPU, const std::string &FS,
                   const TargetMachine &TM);

  SystemZCallingConventionRegisters *getSpecialRegisters() const {
    assert(SpecialRegisters && "Unsupported SystemZ calling convention");
    return SpecialRegisters.get();
  }

  template <class SR> SR &getSpecialRegisters() const {
    return *static_cast<SR *>(getSpecialRegisters());
  }

  const TargetFrameLowering *getFrameLowering() const override {
    return FrameLowering.get();
  }

  template <class TFL> const TFL *getFrameLowering() const {
    return static_cast<const TFL *>(getFrameLowering());
  }

  const SystemZInstrInfo *getInstrInfo() const override { return &InstrInfo; }
  const SystemZRegisterInfo *getRegisterInfo() const override {
    return &InstrInfo.getRegisterInfo();
  }
  const SystemZTargetLowering *getTargetLowering() const override {
    return &TLInfo;
  }
  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
    return &TSInfo;
  }

  // True if the subtarget should run MachineScheduler after aggressive
  // coalescing. This currently replaces the SelectionDAG scheduler with the
  // "source" order scheduler.
  bool enableMachineScheduler() const override { return true; }

  // This is important for reducing register pressure in vector code.
  bool useAA() const override { return true; }

  // Always enable the early if-conversion pass.
  bool enableEarlyIfConversion() const override { return true; }

  // Enable tracking of subregister liveness in register allocator.
  bool enableSubRegLiveness() const override;

  // Automatically generated by tblgen.
  void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);

// Getters for SubtargetFeatures defined in tablegen.
#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
  bool GETTER() const { return ATTRIBUTE; }
#include "SystemZGenSubtargetInfo.inc"

  bool isXRaySupported() const override { return true; }

  bool isAddressedViaADA(const GlobalValue *GV) const;

  // Return true if GV can be accessed using LARL for reloc model RM
  // and code model CM.
  bool isPC32DBLSymbol(const GlobalValue *GV, CodeModel::Model CM) const;

  bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }

  // Returns TRUE if we are generating GOFF object code
  bool isTargetGOFF() const { return TargetTriple.isOSBinFormatGOFF(); }

  // Returns TRUE if we are using XPLINK64 linkage convention
  bool isTargetXPLINK64() const { return (isTargetGOFF() && isTargetzOS()); }

  // Returns TRUE if we are generating code for a s390x machine running zOS
  bool isTargetzOS() const { return TargetTriple.isOSzOS(); }
};
} // end namespace llvm

#endif
