1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #ifndef CPU_ALL_H
21: #define CPU_ALL_H
22:
23: #if defined(__arm__) || defined(__sparc__) || defined(__mips__)
24: #define WORDS_ALIGNED
25: #endif
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40: #include "bswap.h"
41:
42: #if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
43: #define BSWAP_NEEDED
44: #endif
45:
46: #ifdef BSWAP_NEEDED
47:
48: static inline uint16_t tswap16(uint16_t s)
49: {
50: return bswap16(s);
51: }
52:
53: static inline uint32_t tswap32(uint32_t s)
54: {
55: return bswap32(s);
56: }
57:
58: static inline uint64_t tswap64(uint64_t s)
59: {
60: return bswap64(s);
61: }
62:
63: static inline void tswap16s(uint16_t *s)
64: {
65: *s = bswap16(*s);
66: }
67:
68: static inline void tswap32s(uint32_t *s)
69: {
70: *s = bswap32(*s);
71: }
72:
73: static inline void tswap64s(uint64_t *s)
74: {
75: *s = bswap64(*s);
76: }
77:
78: #else
79:
80: static inline uint16_t tswap16(uint16_t s)
81: {
82: return s;
83: }
84:
85: static inline uint32_t tswap32(uint32_t s)
86: {
87: return s;
88: }
89:
90: static inline uint64_t tswap64(uint64_t s)
91: {
92: return s;
93: }
94:
95: static inline void tswap16s(uint16_t *s)
96: {
97: }
98:
99: static inline void tswap32s(uint32_t *s)
100: {
101: }
102:
103: static inline void tswap64s(uint64_t *s)
104: {
105: }
106:
107: #endif
108:
109: #if TARGET_LONG_SIZE == 4
110: #define tswapl(s) tswap32(s)
111: #define tswapls(s) tswap32s((uint32_t *)(s))
112: #define bswaptls(s) bswap32s(s)
113: #else
114: #define tswapl(s) tswap64(s)
115: #define tswapls(s) tswap64s((uint64_t *)(s))
116: #define bswaptls(s) bswap64s(s)
117: #endif
118:
119:
120:
121: typedef union {
122: float64 d;
123: #if defined(WORDS_BIGENDIAN) \
124: || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
125: struct {
126: uint32_t upper;
127: uint32_t lower;
128: } l;
129: #else
130: struct {
131: uint32_t lower;
132: uint32_t upper;
133: } l;
134: #endif
135: uint64_t ll;
136: } CPU_DoubleU;
137:
138: #ifdef TARGET_SPARC
139: typedef union {
140: float128 q;
141: #if defined(WORDS_BIGENDIAN) \
142: || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
143: struct {
144: uint32_t upmost;
145: uint32_t upper;
146: uint32_t lower;
147: uint32_t lowest;
148: } l;
149: struct {
150: uint64_t upper;
151: uint64_t lower;
152: } ll;
153: #else
154: struct {
155: uint32_t lowest;
156: uint32_t lower;
157: uint32_t upper;
158: uint32_t upmost;
159: } l;
160: struct {
161: uint64_t lower;
162: uint64_t upper;
163: } ll;
164: #endif
165: } CPU_QuadU;
166: #endif
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203: static inline int ldub_p(void *ptr)
204: {
205: return *(uint8_t *)ptr;
206: }
207:
208: static inline int ldsb_p(void *ptr)
209: {
210: return *(int8_t *)ptr;
211: }
212:
213: static inline void stb_p(void *ptr, int v)
214: {
215: *(uint8_t *)ptr = v;
216: }
217:
218:
219:
220:
221: #if defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
222:
223:
224: static inline int lduw_le_p(void *ptr)
225: {
226: #ifdef __powerpc__
227: int val;
228: __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
229: return val;
230: #else
231: uint8_t *p = ptr;
232: return p[0] | (p[1] << 8);
233: #endif
234: }
235:
236: static inline int ldsw_le_p(void *ptr)
237: {
238: #ifdef __powerpc__
239: int val;
240: __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
241: return (int16_t)val;
242: #else
243: uint8_t *p = ptr;
244: return (int16_t)(p[0] | (p[1] << 8));
245: #endif
246: }
247:
248: static inline int ldl_le_p(void *ptr)
249: {
250: #ifdef __powerpc__
251: int val;
252: __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
253: return val;
254: #else
255: uint8_t *p = ptr;
256: return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
257: #endif
258: }
259:
260: static inline uint64_t ldq_le_p(void *ptr)
261: {
262: uint8_t *p = ptr;
263: uint32_t v1, v2;
264: v1 = ldl_le_p(p);
265: v2 = ldl_le_p(p + 4);
266: return v1 | ((uint64_t)v2 << 32);
267: }
268:
269: static inline void stw_le_p(void *ptr, int v)
270: {
271: #ifdef __powerpc__
272: __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
273: #else
274: uint8_t *p = ptr;
275: p[0] = v;
276: p[1] = v >> 8;
277: #endif
278: }
279:
280: static inline void stl_le_p(void *ptr, int v)
281: {
282: #ifdef __powerpc__
283: __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
284: #else
285: uint8_t *p = ptr;
286: p[0] = v;
287: p[1] = v >> 8;
288: p[2] = v >> 16;
289: p[3] = v >> 24;
290: #endif
291: }
292:
293: static inline void stq_le_p(void *ptr, uint64_t v)
294: {
295: uint8_t *p = ptr;
296: stl_le_p(p, (uint32_t)v);
297: stl_le_p(p + 4, v >> 32);
298: }
299:
300:
301:
302: static inline float32 ldfl_le_p(void *ptr)
303: {
304: union {
305: float32 f;
306: uint32_t i;
307: } u;
308: u.i = ldl_le_p(ptr);
309: return u.f;
310: }
311:
312: static inline void stfl_le_p(void *ptr, float32 v)
313: {
314: union {
315: float32 f;
316: uint32_t i;
317: } u;
318: u.f = v;
319: stl_le_p(ptr, u.i);
320: }
321:
322: static inline float64 ldfq_le_p(void *ptr)
323: {
324: CPU_DoubleU u;
325: u.l.lower = ldl_le_p(ptr);
326: u.l.upper = ldl_le_p(ptr + 4);
327: return u.d;
328: }
329:
330: static inline void stfq_le_p(void *ptr, float64 v)
331: {
332: CPU_DoubleU u;
333: u.d = v;
334: stl_le_p(ptr, u.l.lower);
335: stl_le_p(ptr + 4, u.l.upper);
336: }
337:
338: #else
339:
340: static inline int lduw_le_p(void *ptr)
341: {
342: return *(uint16_t *)ptr;
343: }
344:
345: static inline int ldsw_le_p(void *ptr)
346: {
347: return *(int16_t *)ptr;
348: }
349:
350: static inline int ldl_le_p(void *ptr)
351: {
352: return *(uint32_t *)ptr;
353: }
354:
355: static inline uint64_t ldq_le_p(void *ptr)
356: {
357: return *(uint64_t *)ptr;
358: }
359:
360: static inline void stw_le_p(void *ptr, int v)
361: {
362: *(uint16_t *)ptr = v;
363: }
364:
365: static inline void stl_le_p(void *ptr, int v)
366: {
367: *(uint32_t *)ptr = v;
368: }
369:
370: static inline void stq_le_p(void *ptr, uint64_t v)
371: {
372: *(uint64_t *)ptr = v;
373: }
374:
375:
376:
377: static inline float32 ldfl_le_p(void *ptr)
378: {
379: return *(float32 *)ptr;
380: }
381:
382: static inline float64 ldfq_le_p(void *ptr)
383: {
384: return *(float64 *)ptr;
385: }
386:
387: static inline void stfl_le_p(void *ptr, float32 v)
388: {
389: *(float32 *)ptr = v;
390: }
391:
392: static inline void stfq_le_p(void *ptr, float64 v)
393: {
394: *(float64 *)ptr = v;
395: }
396: #endif
397:
398: #if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
399:
400: static inline int lduw_be_p(void *ptr)
401: {
402: #if defined(__i386__)
403: int val;
404: asm volatile ("movzwl %1, %0\n"
405: "xchgb %b0, %h0\n"
406: : "=q" (val)
407: : "m" (*(uint16_t *)ptr));
408: return val;
409: #else
410: uint8_t *b = (uint8_t *) ptr;
411: return ((b[0] << 8) | b[1]);
412: #endif
413: }
414:
415: static inline int ldsw_be_p(void *ptr)
416: {
417: #if defined(__i386__)
418: int val;
419: asm volatile ("movzwl %1, %0\n"
420: "xchgb %b0, %h0\n"
421: : "=q" (val)
422: : "m" (*(uint16_t *)ptr));
423: return (int16_t)val;
424: #else
425: uint8_t *b = (uint8_t *) ptr;
426: return (int16_t)((b[0] << 8) | b[1]);
427: #endif
428: }
429:
430: static inline int ldl_be_p(void *ptr)
431: {
432: #if defined(__i386__) || defined(__x86_64__)
433: int val;
434: asm volatile ("movl %1, %0\n"
435: "bswap %0\n"
436: : "=r" (val)
437: : "m" (*(uint32_t *)ptr));
438: return val;
439: #else
440: uint8_t *b = (uint8_t *) ptr;
441: return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
442: #endif
443: }
444:
445: static inline uint64_t ldq_be_p(void *ptr)
446: {
447: uint32_t a,b;
448: a = ldl_be_p(ptr);
449: b = ldl_be_p(ptr+4);
450: return (((uint64_t)a<<32)|b);
451: }
452:
453: static inline void stw_be_p(void *ptr, int v)
454: {
455: #if defined(__i386__)
456: asm volatile ("xchgb %b0, %h0\n"
457: "movw %w0, %1\n"
458: : "=q" (v)
459: : "m" (*(uint16_t *)ptr), "0" (v));
460: #else
461: uint8_t *d = (uint8_t *) ptr;
462: d[0] = v >> 8;
463: d[1] = v;
464: #endif
465: }
466:
467: static inline void stl_be_p(void *ptr, int v)
468: {
469: #if defined(__i386__) || defined(__x86_64__)
470: asm volatile ("bswap %0\n"
471: "movl %0, %1\n"
472: : "=r" (v)
473: : "m" (*(uint32_t *)ptr), "0" (v));
474: #else
475: uint8_t *d = (uint8_t *) ptr;
476: d[0] = v >> 24;
477: d[1] = v >> 16;
478: d[2] = v >> 8;
479: d[3] = v;
480: #endif
481: }
482:
483: static inline void stq_be_p(void *ptr, uint64_t v)
484: {
485: stl_be_p(ptr, v >> 32);
486: stl_be_p(ptr + 4, v);
487: }
488:
489:
490:
491: static inline float32 ldfl_be_p(void *ptr)
492: {
493: union {
494: float32 f;
495: uint32_t i;
496: } u;
497: u.i = ldl_be_p(ptr);
498: return u.f;
499: }
500:
501: static inline void stfl_be_p(void *ptr, float32 v)
502: {
503: union {
504: float32 f;
505: uint32_t i;
506: } u;
507: u.f = v;
508: stl_be_p(ptr, u.i);
509: }
510:
511: static inline float64 ldfq_be_p(void *ptr)
512: {
513: CPU_DoubleU u;
514: u.l.upper = ldl_be_p(ptr);
515: u.l.lower = ldl_be_p(ptr + 4);
516: return u.d;
517: }
518:
519: static inline void stfq_be_p(void *ptr, float64 v)
520: {
521: CPU_DoubleU u;
522: u.d = v;
523: stl_be_p(ptr, u.l.upper);
524: stl_be_p(ptr + 4, u.l.lower);
525: }
526:
527: #else
528:
529: static inline int lduw_be_p(void *ptr)
530: {
531: return *(uint16_t *)ptr;
532: }
533:
534: static inline int ldsw_be_p(void *ptr)
535: {
536: return *(int16_t *)ptr;
537: }
538:
539: static inline int ldl_be_p(void *ptr)
540: {
541: return *(uint32_t *)ptr;
542: }
543:
544: static inline uint64_t ldq_be_p(void *ptr)
545: {
546: return *(uint64_t *)ptr;
547: }
548:
549: static inline void stw_be_p(void *ptr, int v)
550: {
551: *(uint16_t *)ptr = v;
552: }
553:
554: static inline void stl_be_p(void *ptr, int v)
555: {
556: *(uint32_t *)ptr = v;
557: }
558:
559: static inline void stq_be_p(void *ptr, uint64_t v)
560: {
561: *(uint64_t *)ptr = v;
562: }
563:
564:
565:
566: static inline float32 ldfl_be_p(void *ptr)
567: {
568: return *(float32 *)ptr;
569: }
570:
571: static inline float64 ldfq_be_p(void *ptr)
572: {
573: return *(float64 *)ptr;
574: }
575:
576: static inline void stfl_be_p(void *ptr, float32 v)
577: {
578: *(float32 *)ptr = v;
579: }
580:
581: static inline void stfq_be_p(void *ptr, float64 v)
582: {
583: *(float64 *)ptr = v;
584: }
585:
586: #endif
587:
588:
589: #if defined(TARGET_WORDS_BIGENDIAN)
590: #define lduw_p(p) lduw_be_p(p)
591: #define ldsw_p(p) ldsw_be_p(p)
592: #define ldl_p(p) ldl_be_p(p)
593: #define ldq_p(p) ldq_be_p(p)
594: #define ldfl_p(p) ldfl_be_p(p)
595: #define ldfq_p(p) ldfq_be_p(p)
596: #define stw_p(p, v) stw_be_p(p, v)
597: #define stl_p(p, v) stl_be_p(p, v)
598: #define stq_p(p, v) stq_be_p(p, v)
599: #define stfl_p(p, v) stfl_be_p(p, v)
600: #define stfq_p(p, v) stfq_be_p(p, v)
601: #else
602: #define lduw_p(p) lduw_le_p(p)
603: #define ldsw_p(p) ldsw_le_p(p)
604: #define ldl_p(p) ldl_le_p(p)
605: #define ldq_p(p) ldq_le_p(p)
606: #define ldfl_p(p) ldfl_le_p(p)
607: #define ldfq_p(p) ldfq_le_p(p)
608: #define stw_p(p, v) stw_le_p(