Blame libcpu/memory-access.h

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