thunk.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Generic thunking code to convert data between host and target CPU
  3. *
  4. * Copyright (c) 2003 Fabrice Bellard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef THUNK_H
  20. #define THUNK_H
  21. #include <inttypes.h>
  22. #include "cpu.h"
  23. /* types enums definitions */
  24. typedef enum argtype {
  25. TYPE_NULL,
  26. TYPE_CHAR,
  27. TYPE_SHORT,
  28. TYPE_INT,
  29. TYPE_LONG,
  30. TYPE_ULONG,
  31. TYPE_PTRVOID, /* pointer on unknown data */
  32. TYPE_LONGLONG,
  33. TYPE_ULONGLONG,
  34. TYPE_PTR,
  35. TYPE_ARRAY,
  36. TYPE_STRUCT,
  37. TYPE_OLDDEVT,
  38. } argtype;
  39. #define MK_PTR(type) TYPE_PTR, type
  40. #define MK_ARRAY(type, size) TYPE_ARRAY, size, type
  41. #define MK_STRUCT(id) TYPE_STRUCT, id
  42. #define THUNK_TARGET 0
  43. #define THUNK_HOST 1
  44. typedef struct {
  45. /* standard struct handling */
  46. const argtype *field_types;
  47. int nb_fields;
  48. int *field_offsets[2];
  49. /* special handling */
  50. void (*convert[2])(void *dst, const void *src);
  51. int size[2];
  52. int align[2];
  53. const char *name;
  54. } StructEntry;
  55. /* Translation table for bitmasks... */
  56. typedef struct bitmask_transtbl {
  57. unsigned int x86_mask;
  58. unsigned int x86_bits;
  59. unsigned int alpha_mask;
  60. unsigned int alpha_bits;
  61. } bitmask_transtbl;
  62. void thunk_register_struct(int id, const char *name, const argtype *types);
  63. void thunk_register_struct_direct(int id, const char *name,
  64. const StructEntry *se1);
  65. const argtype *thunk_convert(void *dst, const void *src,
  66. const argtype *type_ptr, int to_host);
  67. #ifndef NO_THUNK_TYPE_SIZE
  68. extern StructEntry struct_entries[];
  69. int thunk_type_size_array(const argtype *type_ptr, int is_host);
  70. int thunk_type_align_array(const argtype *type_ptr, int is_host);
  71. static inline int thunk_type_size(const argtype *type_ptr, int is_host)
  72. {
  73. int type, size;
  74. const StructEntry *se;
  75. type = *type_ptr;
  76. switch(type) {
  77. case TYPE_CHAR:
  78. return 1;
  79. case TYPE_SHORT:
  80. return 2;
  81. case TYPE_INT:
  82. return 4;
  83. case TYPE_LONGLONG:
  84. case TYPE_ULONGLONG:
  85. return 8;
  86. case TYPE_LONG:
  87. case TYPE_ULONG:
  88. case TYPE_PTRVOID:
  89. case TYPE_PTR:
  90. if (is_host) {
  91. return sizeof(void *);
  92. } else {
  93. return TARGET_ABI_BITS / 8;
  94. }
  95. break;
  96. case TYPE_OLDDEVT:
  97. if (is_host) {
  98. #if defined(HOST_X86_64)
  99. return 8;
  100. #elif defined(HOST_ALPHA) || defined(HOST_IA64) || defined(HOST_MIPS) || \
  101. defined(HOST_PARISC) || defined(HOST_SPARC64)
  102. return 4;
  103. #elif defined(HOST_PPC)
  104. return sizeof(void *);
  105. #else
  106. return 2;
  107. #endif
  108. } else {
  109. #if defined(TARGET_X86_64)
  110. return 8;
  111. #elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \
  112. defined(TARGET_PARISC) || defined(TARGET_SPARC64)
  113. return 4;
  114. #elif defined(TARGET_PPC)
  115. return TARGET_ABI_BITS / 8;
  116. #else
  117. return 2;
  118. #endif
  119. }
  120. break;
  121. case TYPE_ARRAY:
  122. size = type_ptr[1];
  123. return size * thunk_type_size_array(type_ptr + 2, is_host);
  124. case TYPE_STRUCT:
  125. se = struct_entries + type_ptr[1];
  126. return se->size[is_host];
  127. default:
  128. return -1;
  129. }
  130. }
  131. static inline int thunk_type_align(const argtype *type_ptr, int is_host)
  132. {
  133. int type;
  134. const StructEntry *se;
  135. type = *type_ptr;
  136. switch(type) {
  137. case TYPE_CHAR:
  138. return 1;
  139. case TYPE_SHORT:
  140. return 2;
  141. case TYPE_INT:
  142. return 4;
  143. case TYPE_LONGLONG:
  144. case TYPE_ULONGLONG:
  145. return 8;
  146. case TYPE_LONG:
  147. case TYPE_ULONG:
  148. case TYPE_PTRVOID:
  149. case TYPE_PTR:
  150. if (is_host) {
  151. return sizeof(void *);
  152. } else {
  153. return TARGET_ABI_BITS / 8;
  154. }
  155. break;
  156. case TYPE_OLDDEVT:
  157. return thunk_type_size(type_ptr, is_host);
  158. case TYPE_ARRAY:
  159. return thunk_type_align_array(type_ptr + 2, is_host);
  160. case TYPE_STRUCT:
  161. se = struct_entries + type_ptr[1];
  162. return se->align[is_host];
  163. default:
  164. return -1;
  165. }
  166. }
  167. #endif /* NO_THUNK_TYPE_SIZE */
  168. unsigned int target_to_host_bitmask(unsigned int x86_mask,
  169. const bitmask_transtbl * trans_tbl);
  170. unsigned int host_to_target_bitmask(unsigned int alpha_mask,
  171. const bitmask_transtbl * trans_tbl);
  172. #endif