qemu-cvs-alsa_bitfield
authorAlexander Graf <agraf@suse.de>
Tue, 14 Apr 2009 14:20:50 +0000 (16:20 +0200)
committerJunfeng Dong <junfeng.dong@intel.com>
Tue, 19 Nov 2013 10:08:49 +0000 (18:08 +0800)
Implements TYPE_INTBITFIELD partially. (required for ALSA support)

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
include/exec/user/thunk.h
thunk.c

index 87025c3..6c35e64 100644 (file)
@@ -38,6 +38,7 @@ typedef enum argtype {
     TYPE_ARRAY,
     TYPE_STRUCT,
     TYPE_OLDDEVT,
+    TYPE_INTBITFIELD,
 } argtype;
 
 #define MK_PTR(type) TYPE_PTR, type
@@ -91,6 +92,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
     case TYPE_SHORT:
         return 2;
     case TYPE_INT:
+    case TYPE_INTBITFIELD:
         return 4;
     case TYPE_LONGLONG:
     case TYPE_ULONGLONG:
@@ -153,6 +155,7 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
     case TYPE_SHORT:
         return 2;
     case TYPE_INT:
+    case TYPE_INTBITFIELD:
         return 4;
     case TYPE_LONGLONG:
     case TYPE_ULONGLONG:
diff --git a/thunk.c b/thunk.c
index 3cca047..c6a78ca 100644 (file)
--- a/thunk.c
+++ b/thunk.c
@@ -41,6 +41,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
     case TYPE_CHAR:
     case TYPE_SHORT:
     case TYPE_INT:
+    case TYPE_INTBITFIELD:
     case TYPE_LONGLONG:
     case TYPE_ULONGLONG:
     case TYPE_LONG:
@@ -140,6 +141,26 @@ const argtype *thunk_convert(void *dst, const void *src,
     case TYPE_INT:
         *(uint32_t *)dst = tswap32(*(uint32_t *)src);
         break;
+    case TYPE_INTBITFIELD:
+#if defined(TARGET_I386) && defined(__powerpc__)
+        /* powerpc uses the MSB, whereas i386 uses the LSB
+         * to store the first bit in a field */
+        {
+           unsigned char byte = *(uint8_t *)src;
+            *(uint8_t *)dst  = ((byte >> 7) & 1)
+                            | ((byte >> 5) & 2)
+                            | ((byte >> 3) & 4)
+                            | ((byte >> 1) & 8)
+                            | ((byte << 1) & 16)
+                            | ((byte << 3) & 32)
+                            | ((byte << 5) & 64)
+                            | ((byte << 7) & 128);
+           /* FIXME: implement for bitfields > 1 byte and other archs */
+        }
+#else
+        *(uint32_t *)dst = tswap32(*(uint32_t *)src);
+#endif
+       break;
     case TYPE_LONGLONG:
     case TYPE_ULONGLONG:
         *(uint64_t *)dst = tswap64(*(uint64_t *)src);