/* Copyright (C) 1999-2016 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"

#include "regcache.h"
#include "arm-tdep.h"
#include "arm-linux-tdep.h"

#include "aarch32-linux-nat.h"

/* Supply GP registers contents, stored in REGS, to REGCACHE.  ARM_APCS_32
   is true if the 32-bit mode is in use, otherwise, it is false.  */

void
aarch32_gp_regcache_supply (struct regcache *regcache, uint32_t *regs,
			    int arm_apcs_32)
{
  int regno;

  for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
    regcache_raw_supply (regcache, regno, &regs[regno]);

  if (arm_apcs_32)
    regcache_raw_supply (regcache, ARM_PS_REGNUM, &regs[ARM_CPSR_GREGNUM]);
  else
    regcache_raw_supply (regcache, ARM_PS_REGNUM, &regs[ARM_PC_REGNUM]);

  regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove
			  (get_regcache_arch (regcache), regs[ARM_PC_REGNUM]);
  regcache_raw_supply (regcache, ARM_PC_REGNUM, &regs[ARM_PC_REGNUM]);
}

/* Collect GP registers from REGCACHE to buffer REGS.  ARM_APCS_32 is
   true if the 32-bit mode is in use, otherwise, it is false.  */

void
aarch32_gp_regcache_collect (const struct regcache *regcache, uint32_t *regs,
			     int arm_apcs_32)
{
  int regno;

  for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
    {
      if (REG_VALID == regcache_register_status (regcache, regno))
	regcache_raw_collect (regcache, regno, &regs[regno]);
    }

  if (arm_apcs_32
      && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM))
    regcache_raw_collect (regcache, ARM_PS_REGNUM,
			  &regs[ARM_CPSR_GREGNUM]);
}

/* Supply VFP registers contents, stored in REGS, to REGCACHE.
   VFP_REGISTER_COUNT is the number of VFP registers.  */

void
aarch32_vfp_regcache_supply (struct regcache *regcache, gdb_byte *regs,
			     const int vfp_register_count)
{
  int regno;

  for (regno = 0; regno < vfp_register_count; regno++)
    regcache_raw_supply (regcache, regno + ARM_D0_REGNUM,
			 regs + regno * 8);

  regcache_raw_supply (regcache, ARM_FPSCR_REGNUM,
		       regs + 32 * 8);
}

/* Collect VFP registers from REGCACHE to buffer REGS.
   VFP_REGISTER_COUNT is the number VFP registers.  */

void
aarch32_vfp_regcache_collect (const struct regcache *regcache, gdb_byte *regs,
			      const int vfp_register_count)
{
  int regno;

  for (regno = 0; regno < vfp_register_count; regno++)
    regcache_raw_collect (regcache, regno + ARM_D0_REGNUM, regs + regno * 8);

  regcache_raw_collect (regcache, ARM_FPSCR_REGNUM, regs + 32 * 8);
}
