//===-- HexagonVarargsCallingConvention.h - Calling Conventions -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the functions that assign locations to outgoing function
// arguments. Adapted from the target independent version but this handles
// calls to varargs functions
//
//===----------------------------------------------------------------------===//
//




static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
                                    EVT LocVT, CCValAssign::LocInfo LocInfo,
                                    ISD::ArgFlagsTy ArgFlags,
                                    Hexagon_CCState &State,
                                    int NonVarArgsParams,
                                    int CurrentParam,
                                    bool ForceMem);


static bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
                                 EVT LocVT, CCValAssign::LocInfo LocInfo,
                                 ISD::ArgFlagsTy ArgFlags,
                                 Hexagon_CCState &State,
                                 int NonVarArgsParams,
                                 int CurrentParam,
                                 bool ForceMem) {
  unsigned ByValSize = 0;
  if (ArgFlags.isByVal() &&
      ((ByValSize = ArgFlags.getByValSize()) >
       (MVT(MVT::i64).getSizeInBits() / 8))) {
    ForceMem = true;
  }


  // Only assign registers for named (non varargs) arguments
  if ( !ForceMem && ((NonVarArgsParams == -1) || (CurrentParam <=
                                                  NonVarArgsParams))) {

    if (LocVT == MVT::i32 ||
        LocVT == MVT::i16 ||
        LocVT == MVT::i8 ||
        LocVT == MVT::f32) {
      static const unsigned RegList1[] = {
        Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
        Hexagon::R5
      };
      if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
        State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
                                         LocVT.getSimpleVT(), LocInfo));
        return false;
      }
    }

    if (LocVT == MVT::i64 ||
        LocVT == MVT::f64) {
      static const unsigned RegList2[] = {
        Hexagon::D0, Hexagon::D1, Hexagon::D2
      };
      if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
        State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
                                         LocVT.getSimpleVT(), LocInfo));
        return false;
      }
    }
  }

  const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
  unsigned Alignment =
    State.getTarget().getTargetData()->getABITypeAlignment(ArgTy);
  unsigned Size =
    State.getTarget().getTargetData()->getTypeSizeInBits(ArgTy) / 8;

  // If it's passed by value, then we need the size of the aggregate not of
  // the pointer.
  if (ArgFlags.isByVal()) {
    Size = ByValSize;

    // Hexagon_TODO: Get the alignment of the contained type here.
    Alignment = 8;
  }

  unsigned Offset3 = State.AllocateStack(Size, Alignment);
  State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
                                   LocVT.getSimpleVT(), LocInfo));
  return false;
}


static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
                                    EVT LocVT, CCValAssign::LocInfo LocInfo,
                                    ISD::ArgFlagsTy ArgFlags,
                                    Hexagon_CCState &State,
                                    int NonVarArgsParams,
                                    int CurrentParam,
                                    bool ForceMem) {

  if (LocVT == MVT::i32 ||
      LocVT == MVT::f32) {
    static const unsigned RegList1[] = {
      Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
      Hexagon::R5
    };
    if (unsigned Reg = State.AllocateReg(RegList1, 6)) {
      State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
                                       LocVT.getSimpleVT(), LocInfo));
      return false;
    }
  }

  if (LocVT == MVT::i64 ||
      LocVT == MVT::f64) {
    static const unsigned RegList2[] = {
      Hexagon::D0, Hexagon::D1, Hexagon::D2
    };
    if (unsigned Reg = State.AllocateReg(RegList2, 3)) {
      State.addLoc(CCValAssign::getReg(ValNo, ValVT.getSimpleVT(), Reg,
                                       LocVT.getSimpleVT(), LocInfo));
      return false;
    }
  }

  const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
  unsigned Alignment =
    State.getTarget().getTargetData()->getABITypeAlignment(ArgTy);
  unsigned Size =
    State.getTarget().getTargetData()->getTypeSizeInBits(ArgTy) / 8;

  unsigned Offset3 = State.AllocateStack(Size, Alignment);
  State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
                                   LocVT.getSimpleVT(), LocInfo));
  return false;
}
