Blame libcpu/memory-access.h

Packit 032894
/* Unaligned memory access functionality.
Packit 032894
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008 Red Hat, Inc.
Packit 032894
   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifndef _MEMORY_ACCESS_H
Packit 032894
#define _MEMORY_ACCESS_H 1
Packit 032894
Packit 032894
#include <byteswap.h>
Packit 032894
#include <endian.h>
Packit 032894
#include <limits.h>
Packit 032894
#include <stdint.h>
Packit 032894
Packit 032894
Packit 032894
/* When loading this file we require the macro MACHINE_ENCODING to be
Packit 032894
   defined to signal the endianness of the architecture which is
Packit 032894
   defined.  */
Packit 032894
#ifndef MACHINE_ENCODING
Packit 032894
# error "MACHINE_ENCODING needs to be defined"
Packit 032894
#endif
Packit 032894
#if MACHINE_ENCODING != __BIG_ENDIAN && MACHINE_ENCODING != __LITTLE_ENDIAN
Packit 032894
# error "MACHINE_ENCODING must signal either big or little endian"
Packit 032894
#endif
Packit 032894
Packit 032894
Packit 032894
/* We use simple memory access functions in case the hardware allows it.
Packit 032894
   The caller has to make sure we don't have alias problems.  */
Packit 032894
#if ALLOW_UNALIGNED
Packit 032894
Packit 032894
# define read_2ubyte_unaligned(Addr) \
Packit 032894
  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
Packit 032894
   ? bswap_16 (*((const uint16_t *) (Addr)))				      \
Packit 032894
   : *((const uint16_t *) (Addr)))
Packit 032894
# define read_2sbyte_unaligned(Addr) \
Packit 032894
  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
Packit 032894
   ? (int16_t) bswap_16 (*((const int16_t *) (Addr)))			      \
Packit 032894
   : *((const int16_t *) (Addr)))
Packit 032894
Packit 032894
# define read_4ubyte_unaligned_noncvt(Addr) \
Packit 032894
   *((const uint32_t *) (Addr))
Packit 032894
# define read_4ubyte_unaligned(Addr) \
Packit 032894
  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
Packit 032894
   ? bswap_32 (*((const uint32_t *) (Addr)))				      \
Packit 032894
   : *((const uint32_t *) (Addr)))
Packit 032894
# define read_4sbyte_unaligned(Addr) \
Packit 032894
  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
Packit 032894
   ? (int32_t) bswap_32 (*((const int32_t *) (Addr)))			      \
Packit 032894
   : *((const int32_t *) (Addr)))
Packit 032894
Packit 032894
# define read_8ubyte_unaligned(Addr) \
Packit 032894
  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
Packit 032894
   ? bswap_64 (*((const uint64_t *) (Addr)))				      \
Packit 032894
   : *((const uint64_t *) (Addr)))
Packit 032894
# define read_8sbyte_unaligned(Addr) \
Packit 032894
  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
Packit 032894
   ? (int64_t) bswap_64 (*((const int64_t *) (Addr)))			      \
Packit 032894
   : *((const int64_t *) (Addr)))
Packit 032894
Packit 032894
#else
Packit 032894
Packit 032894
union unaligned
Packit 032894
  {
Packit 032894
    void *p;
Packit 032894
    uint16_t u2;
Packit 032894
    uint32_t u4;
Packit 032894
    uint64_t u8;
Packit 032894
    int16_t s2;
Packit 032894
    int32_t s4;
Packit 032894
    int64_t s8;
Packit 032894
  } attribute_packed;
Packit 032894
Packit 032894
static inline uint16_t
Packit 032894
read_2ubyte_unaligned (const void *p)
Packit 032894
{
Packit 032894
  const union unaligned *up = p;
Packit 032894
  if (MACHINE_ENCODING != __BYTE_ORDER)
Packit 032894
    return bswap_16 (up->u2);
Packit 032894
  return up->u2;
Packit 032894
}
Packit 032894
static inline int16_t
Packit 032894
read_2sbyte_unaligned (const void *p)
Packit 032894
{
Packit 032894
  const union unaligned *up = p;
Packit 032894
  if (MACHINE_ENCODING != __BYTE_ORDER)
Packit 032894
    return (int16_t) bswap_16 (up->u2);
Packit 032894
  return up->s2;
Packit 032894
}
Packit 032894
Packit 032894
static inline uint32_t
Packit 032894
read_4ubyte_unaligned_noncvt (const void *p)
Packit 032894
{
Packit 032894
  const union unaligned *up = p;
Packit 032894
  return up->u4;
Packit 032894
}
Packit 032894
static inline uint32_t
Packit 032894
read_4ubyte_unaligned (const void *p)
Packit 032894
{
Packit 032894
  const union unaligned *up = p;
Packit 032894
  if (MACHINE_ENCODING != __BYTE_ORDER)
Packit 032894
    return bswap_32 (up->u4);
Packit 032894
  return up->u4;
Packit 032894
}
Packit 032894
static inline int32_t
Packit 032894
read_4sbyte_unaligned (const void *p)
Packit 032894
{
Packit 032894
  const union unaligned *up = p;
Packit 032894
  if (MACHINE_ENCODING != __BYTE_ORDER)
Packit 032894
    return (int32_t) bswap_32 (up->u4);
Packit 032894
  return up->s4;
Packit 032894
}
Packit 032894
Packit 032894
static inline uint64_t
Packit 032894
read_8ubyte_unaligned (const void *p)
Packit 032894
{
Packit 032894
  const union unaligned *up = p;
Packit 032894
  if (MACHINE_ENCODING != __BYTE_ORDER)
Packit 032894
    return bswap_64 (up->u8);
Packit 032894
  return up->u8;
Packit 032894
}
Packit 032894
static inline int64_t
Packit 032894
read_8sbyte_unaligned (const void *p)
Packit 032894
{
Packit 032894
  const union unaligned *up = p;
Packit 032894
  if (MACHINE_ENCODING != __BYTE_ORDER)
Packit 032894
    return (int64_t) bswap_64 (up->u8);
Packit 032894
  return up->s8;
Packit 032894
}
Packit 032894
Packit 032894
#endif	/* allow unaligned */
Packit 032894
Packit 032894
Packit 032894
#define read_2ubyte_unaligned_inc(Addr) \
Packit 032894
  ({ uint16_t t_ = read_2ubyte_unaligned (Addr);			      \
Packit 032894
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
Packit 032894
     t_; })
Packit 032894
#define read_2sbyte_unaligned_inc(Addr) \
Packit 032894
  ({ int16_t t_ = read_2sbyte_unaligned (Addr);				      \
Packit 032894
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
Packit 032894
     t_; })
Packit 032894
Packit 032894
#define read_4ubyte_unaligned_inc(Addr) \
Packit 032894
  ({ uint32_t t_ = read_4ubyte_unaligned (Addr);			      \
Packit 032894
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
Packit 032894
     t_; })
Packit 032894
#define read_4sbyte_unaligned_inc(Addr) \
Packit 032894
  ({ int32_t t_ = read_4sbyte_unaligned (Addr);				      \
Packit 032894
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
Packit 032894
     t_; })
Packit 032894
Packit 032894
#define read_8ubyte_unaligned_inc(Addr) \
Packit 032894
  ({ uint64_t t_ = read_8ubyte_unaligned (Addr);			      \
Packit 032894
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
Packit 032894
     t_; })
Packit 032894
#define read_8sbyte_unaligned_inc(Addr) \
Packit 032894
  ({ int64_t t_ = read_8sbyte_unaligned (Addr);				      \
Packit 032894
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
Packit 032894
     t_; })
Packit 032894
Packit 032894
#endif	/* memory-access.h */