File:  [Qemu by Fabrice Bellard] / qemu / thunk.h
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:20:51 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, qemu1000, qemu0151, qemu0150, qemu0141, qemu0140, qemu0130, qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, qemu0111, qemu0110, HEAD
qemu 0.11.0

    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: 
   22: #include <inttypes.h>
   23: #include "cpu.h"
   24: 
   25: /* types enums definitions */
   26: 
   27: typedef enum argtype {
   28:     TYPE_NULL,
   29:     TYPE_CHAR,
   30:     TYPE_SHORT,
   31:     TYPE_INT,
   32:     TYPE_LONG,
   33:     TYPE_ULONG,
   34:     TYPE_PTRVOID, /* pointer on unknown data */
   35:     TYPE_LONGLONG,
   36:     TYPE_ULONGLONG,
   37:     TYPE_PTR,
   38:     TYPE_ARRAY,
   39:     TYPE_STRUCT,
   40: } argtype;
   41: 
   42: #define MK_PTR(type) TYPE_PTR, type
   43: #define MK_ARRAY(type, size) TYPE_ARRAY, size, type
   44: #define MK_STRUCT(id) TYPE_STRUCT, id
   45: 
   46: #define THUNK_TARGET 0
   47: #define THUNK_HOST   1
   48: 
   49: typedef struct {
   50:     /* standard struct handling */
   51:     const argtype *field_types;
   52:     int nb_fields;
   53:     int *field_offsets[2];
   54:     /* special handling */
   55:     void (*convert[2])(void *dst, const void *src);
   56:     int size[2];
   57:     int align[2];
   58:     const char *name;
   59: } StructEntry;
   60: 
   61: /* Translation table for bitmasks... */
   62: typedef struct bitmask_transtbl {
   63: 	unsigned int	x86_mask;
   64: 	unsigned int	x86_bits;
   65: 	unsigned int	alpha_mask;
   66: 	unsigned int	alpha_bits;
   67: } bitmask_transtbl;
   68: 
   69: void thunk_register_struct(int id, const char *name, const argtype *types);
   70: void thunk_register_struct_direct(int id, const char *name,
   71:                                   const StructEntry *se1);
   72: const argtype *thunk_convert(void *dst, const void *src,
   73:                              const argtype *type_ptr, int to_host);
   74: #ifndef NO_THUNK_TYPE_SIZE
   75: 
   76: extern StructEntry struct_entries[];
   77: 
   78: int thunk_type_size_array(const argtype *type_ptr, int is_host);
   79: int thunk_type_align_array(const argtype *type_ptr, int is_host);
   80: 
   81: static inline int thunk_type_size(const argtype *type_ptr, int is_host)
   82: {
   83:     int type, size;
   84:     const StructEntry *se;
   85: 
   86:     type = *type_ptr;
   87:     switch(type) {
   88:     case TYPE_CHAR:
   89:         return 1;
   90:     case TYPE_SHORT:
   91:         return 2;
   92:     case TYPE_INT:
   93:         return 4;
   94:     case TYPE_LONGLONG:
   95:     case TYPE_ULONGLONG:
   96:         return 8;
   97:     case TYPE_LONG:
   98:     case TYPE_ULONG:
   99:     case TYPE_PTRVOID:
  100:     case TYPE_PTR:
  101:         if (is_host) {
  102:             return HOST_LONG_SIZE;
  103:         } else {
  104:             return TARGET_ABI_BITS / 8;
  105:         }
  106:         break;
  107:     case TYPE_ARRAY:
  108:         size = type_ptr[1];
  109:         return size * thunk_type_size_array(type_ptr + 2, is_host);
  110:     case TYPE_STRUCT:
  111:         se = struct_entries + type_ptr[1];
  112:         return se->size[is_host];
  113:     default:
  114:         return -1;
  115:     }
  116: }
  117: 
  118: static inline int thunk_type_align(const argtype *type_ptr, int is_host)
  119: {
  120:     int type;
  121:     const StructEntry *se;
  122: 
  123:     type = *type_ptr;
  124:     switch(type) {
  125:     case TYPE_CHAR:
  126:         return 1;
  127:     case TYPE_SHORT:
  128:         return 2;
  129:     case TYPE_INT:
  130:         return 4;
  131:     case TYPE_LONGLONG:
  132:     case TYPE_ULONGLONG:
  133:         return 8;
  134:     case TYPE_LONG:
  135:     case TYPE_ULONG:
  136:     case TYPE_PTRVOID:
  137:     case TYPE_PTR:
  138:         if (is_host) {
  139:             return HOST_LONG_SIZE;
  140:         } else {
  141:             return TARGET_ABI_BITS / 8;
  142:         }
  143:         break;
  144:     case TYPE_ARRAY:
  145:         return thunk_type_align_array(type_ptr + 2, is_host);
  146:     case TYPE_STRUCT:
  147:         se = struct_entries + type_ptr[1];
  148:         return se->align[is_host];
  149:     default:
  150:         return -1;
  151:     }
  152: }
  153: 
  154: #endif /* NO_THUNK_TYPE_SIZE */
  155: 
  156: unsigned int target_to_host_bitmask(unsigned int x86_mask,
  157:                                     const bitmask_transtbl * trans_tbl);
  158: unsigned int host_to_target_bitmask(unsigned int alpha_mask,
  159:                                     const bitmask_transtbl * trans_tbl);
  160: 
  161: #endif

unix.superglobalmegacorp.com