00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef THUNK_H
00021 #define THUNK_H
00022
00023 #include <inttypes.h>
00024 #include "cpu.h"
00025
00026
00027
00028 typedef enum argtype {
00029 TYPE_NULL,
00030 TYPE_CHAR,
00031 TYPE_SHORT,
00032 TYPE_INT,
00033 TYPE_LONG,
00034 TYPE_ULONG,
00035 TYPE_PTRVOID,
00036 TYPE_LONGLONG,
00037 TYPE_ULONGLONG,
00038 TYPE_PTR,
00039 TYPE_ARRAY,
00040 TYPE_STRUCT,
00041 } argtype;
00042
00043 #define MK_PTR(type) TYPE_PTR, type
00044 #define MK_ARRAY(type, size) TYPE_ARRAY, size, type
00045 #define MK_STRUCT(id) TYPE_STRUCT, id
00046
00047 #define THUNK_TARGET 0
00048 #define THUNK_HOST 1
00049
00050 typedef struct {
00051
00052 const argtype *field_types;
00053 int nb_fields;
00054 int *field_offsets[2];
00055
00056 void (*convert[2])(void *dst, const void *src);
00057 int size[2];
00058 int align[2];
00059 const char *name;
00060 } StructEntry;
00061
00062
00063 typedef struct bitmask_transtbl {
00064 unsigned int x86_mask;
00065 unsigned int x86_bits;
00066 unsigned int alpha_mask;
00067 unsigned int alpha_bits;
00068 } bitmask_transtbl;
00069
00070 void thunk_register_struct(int id, const char *name, const argtype *types);
00071 void thunk_register_struct_direct(int id, const char *name,
00072 const StructEntry *se1);
00073 const argtype *thunk_convert(void *dst, const void *src,
00074 const argtype *type_ptr, int to_host);
00075 #ifndef NO_THUNK_TYPE_SIZE
00076
00077 extern StructEntry struct_entries[];
00078
00079 int thunk_type_size_array(const argtype *type_ptr, int is_host);
00080 int thunk_type_align_array(const argtype *type_ptr, int is_host);
00081
00082 static inline int thunk_type_size(const argtype *type_ptr, int is_host)
00083 {
00084 int type, size;
00085 const StructEntry *se;
00086
00087 type = *type_ptr;
00088 switch(type) {
00089 case TYPE_CHAR:
00090 return 1;
00091 case TYPE_SHORT:
00092 return 2;
00093 case TYPE_INT:
00094 return 4;
00095 case TYPE_LONGLONG:
00096 case TYPE_ULONGLONG:
00097 return 8;
00098 case TYPE_LONG:
00099 case TYPE_ULONG:
00100 case TYPE_PTRVOID:
00101 case TYPE_PTR:
00102 if (is_host) {
00103 return HOST_LONG_SIZE;
00104 } else {
00105 return TARGET_ABI_BITS / 8;
00106 }
00107 break;
00108 case TYPE_ARRAY:
00109 size = type_ptr[1];
00110 return size * thunk_type_size_array(type_ptr + 2, is_host);
00111 case TYPE_STRUCT:
00112 se = struct_entries + type_ptr[1];
00113 return se->size[is_host];
00114 default:
00115 return -1;
00116 }
00117 }
00118
00119 static inline int thunk_type_align(const argtype *type_ptr, int is_host)
00120 {
00121 int type;
00122 const StructEntry *se;
00123
00124 type = *type_ptr;
00125 switch(type) {
00126 case TYPE_CHAR:
00127 return 1;
00128 case TYPE_SHORT:
00129 return 2;
00130 case TYPE_INT:
00131 return 4;
00132 case TYPE_LONGLONG:
00133 case TYPE_ULONGLONG:
00134 return 8;
00135 case TYPE_LONG:
00136 case TYPE_ULONG:
00137 case TYPE_PTRVOID:
00138 case TYPE_PTR:
00139 if (is_host) {
00140 return HOST_LONG_SIZE;
00141 } else {
00142 return TARGET_ABI_BITS / 8;
00143 }
00144 break;
00145 case TYPE_ARRAY:
00146 return thunk_type_align_array(type_ptr + 2, is_host);
00147 case TYPE_STRUCT:
00148 se = struct_entries + type_ptr[1];
00149 return se->align[is_host];
00150 default:
00151 return -1;
00152 }
00153 }
00154
00155 #endif
00156
00157 unsigned int target_to_host_bitmask(unsigned int x86_mask,
00158 const bitmask_transtbl * trans_tbl);
00159 unsigned int host_to_target_bitmask(unsigned int alpha_mask,
00160 const bitmask_transtbl * trans_tbl);
00161
00162 #endif