OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [sim/] [d10v/] [endian.c] - Blame information for rev 473

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* If we're being compiled as a .c file, rather than being included in
2
   d10v_sim.h, then ENDIAN_INLINE won't be defined yet.  */
3
 
4
#ifndef ENDIAN_INLINE
5
#define NO_ENDIAN_INLINE
6
#include "d10v_sim.h"
7
#define ENDIAN_INLINE
8
#endif
9
 
10
ENDIAN_INLINE uint16
11
get_word (x)
12
      uint8 *x;
13
{
14
#if (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
15
 
16
  unsigned short word = *(unsigned short *)x;
17
  __asm__ ("xchgb %b0,%h0" : "=q" (word) : "0" (word));
18
  return word;
19
 
20
#elif defined(WORDS_BIGENDIAN)
21
  /* It is safe to do this on big endian hosts, since the d10v requires that words be
22
     aligned on 16-bit boundaries.  */
23
  return *(uint16 *)x;
24
 
25
#else
26
  return ((uint16)x[0]<<8) + x[1];
27
#endif
28
}
29
 
30
ENDIAN_INLINE uint32
31
get_longword (x)
32
      uint8 *x;
33
{
34
#if (defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__) && defined(USE_BSWAP)
35
 
36
  unsigned int long_word = *(unsigned *)x;
37
  __asm__ ("bswap %0" : "=r" (long_word) : "0" (long_word));
38
  return long_word;
39
 
40
#elif (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
41
 
42
  unsigned int long_word = *(unsigned *)x;
43
  __asm__("xchgb %b0,%h0\n\t"           /* swap lower bytes     */
44
          "rorl $16,%0\n\t"             /* swap words           */
45
          "xchgb %b0,%h0"               /* swap higher bytes    */
46
          :"=q" (long_word)
47
          : "0" (long_word));
48
 
49
  return long_word;
50
 
51
#elif (defined(_POWER) && defined(_AIX)) || (defined(__PPC__) && defined(__BIG_ENDIAN__))
52
  /* Power & PowerPC computers in big endian mode can handle unaligned loads&stores */
53
  return *(uint32 *)x;
54
 
55
#elif defined(WORDS_BIGENDIAN)
56
  /* long words must be aligned on at least 16-bit boundaries, so this should be safe.  */
57
  return (((uint32) *(uint16 *)x)<<16) | ((uint32) *(uint16 *)(x+2));
58
 
59
#else
60
  return ((uint32)x[0]<<24) + ((uint32)x[1]<<16) + ((uint32)x[2]<<8) + ((uint32)x[3]);
61
#endif
62
}
63
 
64
ENDIAN_INLINE int64
65
get_longlong (x)
66
      uint8 *x;
67
{
68
  uint32 top = get_longword (x);
69
  uint32 bottom = get_longword (x+4);
70
  return (((int64)top)<<32) | (int64)bottom;
71
}
72
 
73
ENDIAN_INLINE void
74
write_word (addr, data)
75
     uint8 *addr;
76
     uint16 data;
77
{
78
#if (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
79
 
80
  __asm__ ("xchgb %b0,%h0" : "=q" (data) : "0" (data));
81
  *(uint16 *)addr = data;
82
 
83
#elif defined(WORDS_BIGENDIAN)
84
  /* It is safe to do this on big endian hosts, since the d10v requires that words be
85
     aligned on 16-bit boundaries.  */
86
  *(uint16 *)addr = data;
87
 
88
#else
89
  addr[0] = (data >> 8) & 0xff;
90
  addr[1] = data & 0xff;
91
#endif
92
}
93
 
94
ENDIAN_INLINE void
95
write_longword (addr, data)
96
     uint8 *addr;
97
     uint32 data;
98
{
99
#if (defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__) && defined(USE_BSWAP)
100
 
101
  __asm__ ("bswap %0" : "=r" (data) : "0" (data));
102
  *(uint32 *)addr = data;
103
 
104
#elif (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
105
 
106
  __asm__("xchgb %b0,%h0\n\t"           /* swap lower bytes     */
107
          "rorl $16,%0\n\t"             /* swap words           */
108
          "xchgb %b0,%h0"               /* swap higher bytes    */
109
          :"=q" (data)
110
          : "0" (data));
111
 
112
  *(uint32 *)addr = data;
113
 
114
#elif (defined(_POWER) && defined(_AIX)) || (defined(__PPC__) && defined(__BIG_ENDIAN__))
115
  /* Power & PowerPC computers in big endian mode can handle unaligned loads&stores */
116
  *(uint32 *)addr = data;
117
 
118
#elif defined(WORDS_BIGENDIAN)
119
  *(uint16 *)addr = (uint16)(data >> 16);
120
  *(uint16 *)(addr + 2) = (uint16)data;
121
 
122
#else
123
  addr[0] = (data >> 24) & 0xff;
124
  addr[1] = (data >> 16) & 0xff;
125
  addr[2] = (data >> 8) & 0xff;
126
  addr[3] = data & 0xff;
127
#endif
128
}
129
 
130
ENDIAN_INLINE void
131
write_longlong (addr, data)
132
     uint8 *addr;
133
     int64 data;
134
{
135
  write_longword (addr, (uint32)(data >> 32));
136
  write_longword (addr+4, (uint32)data);
137
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.