linux/include/asm-frv/unaligned.h
<<
>>
Prefs
   1/* unaligned.h: unaligned access handler
   2 *
   3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#ifndef _ASM_UNALIGNED_H
  13#define _ASM_UNALIGNED_H
  14
  15
  16/*
  17 * Unaligned accesses on uClinux can't be performed in a fault handler - the
  18 * CPU detects them as imprecise exceptions making this impossible.
  19 *
  20 * With the FR451, however, they are precise, and so we used to fix them up in
  21 * the memory access fault handler.  However, instruction bundling make this
  22 * impractical.  So, now we fall back to using memcpy.
  23 */
  24#ifdef CONFIG_MMU
  25
  26/*
  27 * The asm statement in the macros below is a way to get GCC to copy a
  28 * value from one variable to another without having any clue it's
  29 * actually doing so, so that it won't have any idea that the values
  30 * in the two variables are related.
  31 */
  32
  33#define get_unaligned(ptr) ({                           \
  34        typeof((*(ptr))) __x;                           \
  35        void *__ptrcopy;                                \
  36        asm("" : "=r" (__ptrcopy) : "0" (ptr));         \
  37        memcpy(&__x, __ptrcopy, sizeof(*(ptr)));        \
  38        __x;                                            \
  39})
  40
  41#define put_unaligned(val, ptr) ({                      \
  42        typeof((*(ptr))) __x = (val);                   \
  43        void *__ptrcopy;                                \
  44        asm("" : "=r" (__ptrcopy) : "0" (ptr));         \
  45        memcpy(__ptrcopy, &__x, sizeof(*(ptr)));        \
  46})
  47
  48extern int handle_misalignment(unsigned long esr0, unsigned long ear0, unsigned long epcr0);
  49
  50#else
  51
  52#define get_unaligned(ptr)                                                      \
  53({                                                                              \
  54        typeof(*(ptr)) x;                                                       \
  55        const char *__p = (const char *) (ptr);                                 \
  56                                                                                \
  57        switch (sizeof(x)) {                                                    \
  58        case 1:                                                                 \
  59                x = *(ptr);                                                     \
  60                break;                                                          \
  61        case 2:                                                                 \
  62        {                                                                       \
  63                uint8_t a;                                                      \
  64                asm("   ldub%I2         %M2,%0          \n"                     \
  65                    "   ldub%I3.p       %M3,%1          \n"                     \
  66                    "   slli            %0,#8,%0        \n"                     \
  67                    "   or              %0,%1,%0        \n"                     \
  68                    : "=&r"(x), "=&r"(a)                                        \
  69                    : "m"(__p[0]),  "m"(__p[1])                                 \
  70                    );                                                          \
  71                break;                                                          \
  72        }                                                                       \
  73                                                                                \
  74        case 4:                                                                 \
  75        {                                                                       \
  76                uint8_t a;                                                      \
  77                asm("   ldub%I2         %M2,%0          \n"                     \
  78                    "   ldub%I3.p       %M3,%1          \n"                     \
  79                    "   slli            %0,#8,%0        \n"                     \
  80                    "   or              %0,%1,%0        \n"                     \
  81                    "   ldub%I4.p       %M4,%1          \n"                     \
  82                    "   slli            %0,#8,%0        \n"                     \
  83                    "   or              %0,%1,%0        \n"                     \
  84                    "   ldub%I5.p       %M5,%1          \n"                     \
  85                    "   slli            %0,#8,%0        \n"                     \
  86                    "   or              %0,%1,%0        \n"                     \
  87                    : "=&r"(x), "=&r"(a)                                        \
  88                    : "m"(__p[0]),  "m"(__p[1]), "m"(__p[2]), "m"(__p[3])       \
  89                    );                                                          \
  90                break;                                                          \
  91        }                                                                       \
  92                                                                                \
  93        case 8:                                                                 \
  94        {                                                                       \
  95                union { uint64_t x; u32 y[2]; } z;                              \
  96                uint8_t a;                                                      \
  97                asm("   ldub%I3         %M3,%0          \n"                     \
  98                    "   ldub%I4.p       %M4,%2          \n"                     \
  99                    "   slli            %0,#8,%0        \n"                     \
 100                    "   or              %0,%2,%0        \n"                     \
 101                    "   ldub%I5.p       %M5,%2          \n"                     \
 102                    "   slli            %0,#8,%0        \n"                     \
 103                    "   or              %0,%2,%0        \n"                     \
 104                    "   ldub%I6.p       %M6,%2          \n"                     \
 105                    "   slli            %0,#8,%0        \n"                     \
 106                    "   or              %0,%2,%0        \n"                     \
 107                    "   ldub%I7         %M7,%1          \n"                     \
 108                    "   ldub%I8.p       %M8,%2          \n"                     \
 109                    "   slli            %1,#8,%1        \n"                     \
 110                    "   or              %1,%2,%1        \n"                     \
 111                    "   ldub%I9.p       %M9,%2          \n"                     \
 112                    "   slli            %1,#8,%1        \n"                     \
 113                    "   or              %1,%2,%1        \n"                     \
 114                    "   ldub%I10.p      %M10,%2         \n"                     \
 115                    "   slli            %1,#8,%1        \n"                     \
 116                    "   or              %1,%2,%1        \n"                     \
 117                    : "=&r"(z.y[0]), "=&r"(z.y[1]), "=&r"(a)                    \
 118                    : "m"(__p[0]), "m"(__p[1]), "m"(__p[2]), "m"(__p[3]),       \
 119                      "m"(__p[4]), "m"(__p[5]), "m"(__p[6]), "m"(__p[7])        \
 120                    );                                                          \
 121                x = z.x;                                                        \
 122                break;                                                          \
 123        }                                                                       \
 124                                                                                \
 125        default:                                                                \
 126                x = 0;                                                          \
 127                BUG();                                                          \
 128                break;                                                          \
 129        }                                                                       \
 130                                                                                \
 131        x;                                                                      \
 132})
 133
 134#define put_unaligned(val, ptr)                                                         \
 135do {                                                                                    \
 136        char *__p = (char *) (ptr);                                                     \
 137        int x;                                                                          \
 138                                                                                        \
 139        switch (sizeof(*ptr)) {                                                         \
 140        case 2:                                                                         \
 141        {                                                                               \
 142                asm("   stb%I1.p        %0,%M1          \n"                             \
 143                    "   srli            %0,#8,%0        \n"                             \
 144                    "   stb%I2          %0,%M2          \n"                             \
 145                    : "=r"(x), "=m"(__p[1]),  "=m"(__p[0])                              \
 146                    : "0"(val)                                                          \
 147                    );                                                                  \
 148                break;                                                                  \
 149        }                                                                               \
 150                                                                                        \
 151        case 4:                                                                         \
 152        {                                                                               \
 153                asm("   stb%I1.p        %0,%M1          \n"                             \
 154                    "   srli            %0,#8,%0        \n"                             \
 155                    "   stb%I2.p        %0,%M2          \n"                             \
 156                    "   srli            %0,#8,%0        \n"                             \
 157                    "   stb%I3.p        %0,%M3          \n"                             \
 158                    "   srli            %0,#8,%0        \n"                             \
 159                    "   stb%I4          %0,%M4          \n"                             \
 160                    : "=r"(x), "=m"(__p[3]),  "=m"(__p[2]), "=m"(__p[1]), "=m"(__p[0])  \
 161                    : "0"(val)                                                          \
 162                    );                                                                  \
 163                break;                                                                  \
 164        }                                                                               \
 165                                                                                        \
 166        case 8:                                                                         \
 167        {                                                                               \
 168                uint32_t __high, __low;                                                 \
 169                __high = (uint64_t)val >> 32;                                           \
 170                __low = val & 0xffffffff;                                               \
 171                asm("   stb%I2.p        %0,%M2          \n"                             \
 172                    "   srli            %0,#8,%0        \n"                             \
 173                    "   stb%I3.p        %0,%M3          \n"                             \
 174                    "   srli            %0,#8,%0        \n"                             \
 175                    "   stb%I4.p        %0,%M4          \n"                             \
 176                    "   srli            %0,#8,%0        \n"                             \
 177                    "   stb%I5.p        %0,%M5          \n"                             \
 178                    "   srli            %0,#8,%0        \n"                             \
 179                    "   stb%I6.p        %1,%M6          \n"                             \
 180                    "   srli            %1,#8,%1        \n"                             \
 181                    "   stb%I7.p        %1,%M7          \n"                             \
 182                    "   srli            %1,#8,%1        \n"                             \
 183                    "   stb%I8.p        %1,%M8          \n"                             \
 184                    "   srli            %1,#8,%1        \n"                             \
 185                    "   stb%I9          %1,%M9          \n"                             \
 186                    : "=&r"(__low), "=&r"(__high), "=m"(__p[7]), "=m"(__p[6]),          \
 187                      "=m"(__p[5]), "=m"(__p[4]), "=m"(__p[3]), "=m"(__p[2]),           \
 188                      "=m"(__p[1]), "=m"(__p[0])                                        \
 189                    : "0"(__low), "1"(__high)                                           \
 190                    );                                                                  \
 191                break;                                                                  \
 192        }                                                                               \
 193                                                                                        \
 194        default:                                                                        \
 195                *(ptr) = (val);                                                         \
 196                break;                                                                  \
 197        }                                                                               \
 198} while(0)
 199
 200#endif
 201
 202#endif
 203
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.