Merge branch 'master' of /home/nchip/public_html/qemu into garage-push
[qemu] / thunk.c
diff --git a/thunk.c b/thunk.c
index 0347d6d..6813c9f 100644 (file)
--- a/thunk.c
+++ b/thunk.c
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -31,6 +31,8 @@
 /* XXX: make it dynamic */
 StructEntry struct_entries[MAX_STRUCTS];
 
+static const argtype *thunk_type_next_ptr(const argtype *type_ptr);
+
 static inline const argtype *thunk_type_next(const argtype *type_ptr)
 {
     int type;
@@ -47,9 +49,9 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
     case TYPE_PTRVOID:
         return type_ptr;
     case TYPE_PTR:
-        return thunk_type_next(type_ptr);
+        return thunk_type_next_ptr(type_ptr);
     case TYPE_ARRAY:
-        return thunk_type_next(type_ptr + 1);
+        return thunk_type_next_ptr(type_ptr + 1);
     case TYPE_STRUCT:
         return type_ptr + 1;
     default:
@@ -57,6 +59,11 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
     }
 }
 
+static const argtype *thunk_type_next_ptr(const argtype *type_ptr)
+{
+    return thunk_type_next(type_ptr);
+}
+
 void thunk_register_struct(int id, const char *name, const argtype *types)
 {
     const argtype *type_ptr;
@@ -106,7 +113,8 @@ void thunk_register_struct(int id, const char *name, const argtype *types)
     }
 }
 
-void thunk_register_struct_direct(int id, const char *name, StructEntry *se1)
+void thunk_register_struct_direct(int id, const char *name,
+                                  const StructEntry *se1)
 {
     StructEntry *se;
     se = struct_entries + id;
@@ -147,11 +155,37 @@ const argtype *thunk_convert(void *dst, const void *src,
     case TYPE_ULONG:
     case TYPE_PTRVOID:
         if (to_host) {
-            *(uint64_t *)dst = tswap32(*(uint32_t *)src);
+            if (type == TYPE_LONG) {
+                /* sign extension */
+                *(uint64_t *)dst = (int32_t)tswap32(*(uint32_t *)src);
+            } else {
+                *(uint64_t *)dst = tswap32(*(uint32_t *)src);
+            }
         } else {
             *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
         }
         break;
+#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
+    case TYPE_LONG:
+    case TYPE_ULONG:
+    case TYPE_PTRVOID:
+        *(uint64_t *)dst = tswap64(*(uint64_t *)src);
+        break;
+#elif HOST_LONG_BITS == 32 && TARGET_ABI_BITS == 64
+    case TYPE_LONG:
+    case TYPE_ULONG:
+    case TYPE_PTRVOID:
+        if (to_host) {
+            *(uint32_t *)dst = tswap64(*(uint64_t *)src);
+        } else {
+            if (type == TYPE_LONG) {
+                /* sign extension */
+                *(uint64_t *)dst = tswap64(*(int32_t *)src);
+            } else {
+                *(uint64_t *)dst = tswap64(*(uint32_t *)src);
+            }
+        }
+        break;
 #else
 #warning unsupported conversion
 #endif
@@ -215,9 +249,9 @@ const argtype *thunk_convert(void *dst, const void *src,
  * between X86 and Alpha formats...
  */
 unsigned int target_to_host_bitmask(unsigned int x86_mask,
-                                    bitmask_transtbl * trans_tbl)
+                                    const bitmask_transtbl * trans_tbl)
 {
-    bitmask_transtbl * btp;
+    const bitmask_transtbl *btp;
     unsigned int       alpha_mask = 0;
 
     for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
@@ -229,9 +263,9 @@ unsigned int target_to_host_bitmask(unsigned int x86_mask,
 }
 
 unsigned int host_to_target_bitmask(unsigned int alpha_mask,
-                                    bitmask_transtbl * trans_tbl)
+                                    const bitmask_transtbl * trans_tbl)
 {
-    bitmask_transtbl * btp;
+    const bitmask_transtbl *btp;
     unsigned int       x86_mask = 0;
 
     for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
@@ -241,3 +275,15 @@ unsigned int host_to_target_bitmask(unsigned int alpha_mask,
     }
     return(x86_mask);
 }
+
+#ifndef NO_THUNK_TYPE_SIZE
+int thunk_type_size_array(const argtype *type_ptr, int is_host)
+{
+    return thunk_type_size(type_ptr, is_host);
+}
+
+int thunk_type_align_array(const argtype *type_ptr, int is_host)
+{
+    return thunk_type_align(type_ptr, is_host);
+}
+#endif /* ndef NO_THUNK_TYPE_SIZE */