//===-- W65816RegisterInfo.h - W65816 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 W65816 implementation of the TargetRegisterInfo
// class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_W65816_W65816REGISTERINFO_H
#define LLVM_LIB_TARGET_W65816_W65816REGISTERINFO_H

#include "llvm/CodeGen/TargetRegisterInfo.h"

#define GET_REGINFO_HEADER
#include "W65816GenRegisterInfo.inc"

namespace llvm {

class W65816RegisterInfo : public W65816GenRegisterInfo {
public:
  W65816RegisterInfo();

  const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;

  BitVector getReservedRegs(const MachineFunction &MF) const override;
  const TargetRegisterClass *
  getPointerRegClass(unsigned Kind = 0) const override;

  bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
                           unsigned FIOperandNum,
                           RegScavenger *RS = nullptr) const override;

  Register getFrameRegister(const MachineFunction &MF) const override;

  // Use the FORWARD frame-index elimination pass.  The default
  // backward pass treats the entire call sequence as if SP were
  // already shifted by the full ADJCALLSTACKDOWN amount, which is
  // wrong for our scheme: ADJCALLSTACKDOWN is a no-op and PUSH16
  // shifts SP incrementally.  The forward pass tracks SPAdj per-MI
  // (driven by W65816InstrInfo::getSPAdjust), so a STAfi BEFORE any
  // PUSH16 in the sequence sees SPAdj=0 and writes to the actual
  // local slot, while a LDAfi AFTER a PUSH16 sees SPAdj=2 and
  // accounts for the shift.  Without this override, eval(a*b+c)
  // and similar functions silently corrupt the caller's return
  // address by writing to a "local" that's actually beyond the
  // reserved frame.
  bool eliminateFrameIndicesBackwards() const override { return false; }
};

} // namespace llvm

#endif
