Annotation of qemu/tcg/tcg.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * Tiny Code Generator for QEMU
        !             3:  *
        !             4:  * Copyright (c) 2008 Fabrice Bellard
        !             5:  *
        !             6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !             7:  * of this software and associated documentation files (the "Software"), to deal
        !             8:  * in the Software without restriction, including without limitation the rights
        !             9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            10:  * copies of the Software, and to permit persons to whom the Software is
        !            11:  * furnished to do so, subject to the following conditions:
        !            12:  *
        !            13:  * The above copyright notice and this permission notice shall be included in
        !            14:  * all copies or substantial portions of the Software.
        !            15:  *
        !            16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            22:  * THE SOFTWARE.
        !            23:  */
        !            24: #include "tcg-target.h"
        !            25: 
        !            26: #if TCG_TARGET_REG_BITS == 32
        !            27: typedef int32_t tcg_target_long;
        !            28: typedef uint32_t tcg_target_ulong;
        !            29: #define TCG_PRIlx PRIx32
        !            30: #define TCG_PRIld PRId32
        !            31: #elif TCG_TARGET_REG_BITS == 64
        !            32: typedef int64_t tcg_target_long;
        !            33: typedef uint64_t tcg_target_ulong;
        !            34: #define TCG_PRIlx PRIx64
        !            35: #define TCG_PRIld PRId64
        !            36: #else
        !            37: #error unsupported
        !            38: #endif
        !            39: 
        !            40: #if TCG_TARGET_NB_REGS <= 32
        !            41: typedef uint32_t TCGRegSet;
        !            42: #elif TCG_TARGET_NB_REGS <= 64
        !            43: typedef uint64_t TCGRegSet;
        !            44: #else
        !            45: #error unsupported
        !            46: #endif
        !            47: 
        !            48: enum {
        !            49: #define DEF(s, n, copy_size) INDEX_op_ ## s,
        !            50: #include "tcg-opc.h"
        !            51: #undef DEF
        !            52:     NB_OPS,
        !            53: };
        !            54: 
        !            55: #define tcg_regset_clear(d) (d) = 0
        !            56: #define tcg_regset_set(d, s) (d) = (s)
        !            57: #define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
        !            58: #define tcg_regset_set_reg(d, r) (d) |= 1 << (r)
        !            59: #define tcg_regset_reset_reg(d, r) (d) &= ~(1 << (r))
        !            60: #define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
        !            61: #define tcg_regset_or(d, a, b) (d) = (a) | (b)
        !            62: #define tcg_regset_and(d, a, b) (d) = (a) & (b)
        !            63: #define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
        !            64: #define tcg_regset_not(d, a) (d) = ~(a)
        !            65: 
        !            66: typedef struct TCGRelocation {
        !            67:     struct TCGRelocation *next;
        !            68:     int type;
        !            69:     uint8_t *ptr;
        !            70:     tcg_target_long addend;
        !            71: } TCGRelocation; 
        !            72: 
        !            73: typedef struct TCGLabel {
        !            74:     int has_value;
        !            75:     union {
        !            76:         tcg_target_ulong value;
        !            77:         TCGRelocation *first_reloc;
        !            78:     } u;
        !            79: } TCGLabel;
        !            80: 
        !            81: typedef struct TCGPool {
        !            82:     struct TCGPool *next;
        !            83:     int size;
        !            84:     uint8_t data[0] __attribute__ ((aligned));
        !            85: } TCGPool;
        !            86: 
        !            87: #define TCG_POOL_CHUNK_SIZE 32768
        !            88: 
        !            89: #define TCG_MAX_LABELS 512
        !            90: 
        !            91: #define TCG_MAX_TEMPS 512
        !            92: 
        !            93: /* when the size of the arguments of a called function is smaller than
        !            94:    this value, they are statically allocated in the TB stack frame */
        !            95: #define TCG_STATIC_CALL_ARGS_SIZE 128
        !            96: 
        !            97: typedef int TCGType;
        !            98: 
        !            99: #define TCG_TYPE_I32 0
        !           100: #define TCG_TYPE_I64 1
        !           101: #define TCG_TYPE_COUNT 2 /* number of different types */
        !           102: 
        !           103: #if TCG_TARGET_REG_BITS == 32
        !           104: #define TCG_TYPE_PTR TCG_TYPE_I32
        !           105: #else
        !           106: #define TCG_TYPE_PTR TCG_TYPE_I64
        !           107: #endif
        !           108: 
        !           109: typedef tcg_target_ulong TCGArg;
        !           110: 
        !           111: /* Define a type and accessor macros for varables.  Using a struct is
        !           112:    nice because it gives some level of type safely.  Ideally the compiler
        !           113:    be able to see through all this.  However in practice this is not true,
        !           114:    expecially on targets with braindamaged ABIs (e.g. i386).
        !           115:    We use plain int by default to avoid this runtime overhead.
        !           116:    Users of tcg_gen_* don't need to know about any of this, and should
        !           117:    treat TCGv as an opaque type.
        !           118:    In additon we do typechecking for different types of variables.  TCGv_i32
        !           119:    and TCGv_i64 are 32/64-bit variables respectively.  TCGv and TCGv_ptr
        !           120:    are aliases for target_ulong and host pointer sized values respectively.
        !           121:  */
        !           122: 
        !           123: //#define DEBUG_TCGV 1
        !           124: 
        !           125: #ifdef DEBUG_TCGV
        !           126: 
        !           127: typedef struct
        !           128: {
        !           129:     int i32;
        !           130: } TCGv_i32;
        !           131: 
        !           132: typedef struct
        !           133: {
        !           134:     int i64;
        !           135: } TCGv_i64;
        !           136: 
        !           137: #define MAKE_TCGV_I32(i) __extension__                  \
        !           138:     ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;})
        !           139: #define MAKE_TCGV_I64(i) __extension__                  \
        !           140:     ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;})
        !           141: #define GET_TCGV_I32(t) ((t).i32)
        !           142: #define GET_TCGV_I64(t) ((t).i64)
        !           143: #if TCG_TARGET_REG_BITS == 32
        !           144: #define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
        !           145: #define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
        !           146: #endif
        !           147: 
        !           148: #else /* !DEBUG_TCGV */
        !           149: 
        !           150: typedef int TCGv_i32;
        !           151: typedef int TCGv_i64;
        !           152: #define MAKE_TCGV_I32(x) (x)
        !           153: #define MAKE_TCGV_I64(x) (x)
        !           154: #define GET_TCGV_I32(t) (t)
        !           155: #define GET_TCGV_I64(t) (t)
        !           156: #if TCG_TARGET_REG_BITS == 32
        !           157: #define TCGV_LOW(t) (t)
        !           158: #define TCGV_HIGH(t) ((t) + 1)
        !           159: #endif
        !           160: 
        !           161: #endif /* DEBUG_TCGV */
        !           162: 
        !           163: /* Dummy definition to avoid compiler warnings.  */
        !           164: #define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
        !           165: #define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
        !           166: 
        !           167: /* call flags */
        !           168: #define TCG_CALL_TYPE_MASK      0x000f
        !           169: #define TCG_CALL_TYPE_STD       0x0000 /* standard C call */
        !           170: #define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
        !           171: #define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
        !           172: #define TCG_CALL_TYPE_REGPARM   0x0003 /* i386 style regparm call (3 regs) */
        !           173: /* A pure function only reads its arguments and globals variables and
        !           174:    cannot raise exceptions. Hence a call to a pure function can be
        !           175:    safely suppressed if the return value is not used. */
        !           176: #define TCG_CALL_PURE           0x0010 
        !           177: 
        !           178: /* used to align parameters */
        !           179: #define TCG_CALL_DUMMY_TCGV     MAKE_TCGV_I32(-1)
        !           180: #define TCG_CALL_DUMMY_ARG      ((TCGArg)(-1))
        !           181: 
        !           182: typedef enum {
        !           183:     TCG_COND_EQ,
        !           184:     TCG_COND_NE,
        !           185:     TCG_COND_LT,
        !           186:     TCG_COND_GE,
        !           187:     TCG_COND_LE,
        !           188:     TCG_COND_GT,
        !           189:     /* unsigned */
        !           190:     TCG_COND_LTU,
        !           191:     TCG_COND_GEU,
        !           192:     TCG_COND_LEU,
        !           193:     TCG_COND_GTU,
        !           194: } TCGCond;
        !           195: 
        !           196: #define TEMP_VAL_DEAD  0
        !           197: #define TEMP_VAL_REG   1
        !           198: #define TEMP_VAL_MEM   2
        !           199: #define TEMP_VAL_CONST 3
        !           200: 
        !           201: /* XXX: optimize memory layout */
        !           202: typedef struct TCGTemp {
        !           203:     TCGType base_type;
        !           204:     TCGType type;
        !           205:     int val_type;
        !           206:     int reg;
        !           207:     tcg_target_long val;
        !           208:     int mem_reg;
        !           209:     tcg_target_long mem_offset;
        !           210:     unsigned int fixed_reg:1;
        !           211:     unsigned int mem_coherent:1;
        !           212:     unsigned int mem_allocated:1;
        !           213:     unsigned int temp_local:1; /* If true, the temp is saved accross
        !           214:                                   basic blocks. Otherwise, it is not
        !           215:                                   preserved accross basic blocks. */
        !           216:     unsigned int temp_allocated:1; /* never used for code gen */
        !           217:     /* index of next free temp of same base type, -1 if end */
        !           218:     int next_free_temp;
        !           219:     const char *name;
        !           220: } TCGTemp;
        !           221: 
        !           222: typedef struct TCGHelperInfo {
        !           223:     tcg_target_ulong func;
        !           224:     const char *name;
        !           225: } TCGHelperInfo;
        !           226: 
        !           227: typedef struct TCGContext TCGContext;
        !           228: 
        !           229: struct TCGContext {
        !           230:     uint8_t *pool_cur, *pool_end;
        !           231:     TCGPool *pool_first, *pool_current;
        !           232:     TCGLabel *labels;
        !           233:     int nb_labels;
        !           234:     TCGTemp *temps; /* globals first, temps after */
        !           235:     int nb_globals;
        !           236:     int nb_temps;
        !           237:     /* index of free temps, -1 if none */
        !           238:     int first_free_temp[TCG_TYPE_COUNT * 2]; 
        !           239: 
        !           240:     /* goto_tb support */
        !           241:     uint8_t *code_buf;
        !           242:     unsigned long *tb_next;
        !           243:     uint16_t *tb_next_offset;
        !           244:     uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
        !           245: 
        !           246:     /* liveness analysis */
        !           247:     uint16_t *op_dead_iargs; /* for each operation, each bit tells if the
        !           248:                                 corresponding input argument is dead */
        !           249:     
        !           250:     /* tells in which temporary a given register is. It does not take
        !           251:        into account fixed registers */
        !           252:     int reg_to_temp[TCG_TARGET_NB_REGS];
        !           253:     TCGRegSet reserved_regs;
        !           254:     tcg_target_long current_frame_offset;
        !           255:     tcg_target_long frame_start;
        !           256:     tcg_target_long frame_end;
        !           257:     int frame_reg;
        !           258: 
        !           259:     uint8_t *code_ptr;
        !           260:     TCGTemp static_temps[TCG_MAX_TEMPS];
        !           261: 
        !           262:     TCGHelperInfo *helpers;
        !           263:     int nb_helpers;
        !           264:     int allocated_helpers;
        !           265:     int helpers_sorted;
        !           266: 
        !           267: #ifdef CONFIG_PROFILER
        !           268:     /* profiling info */
        !           269:     int64_t tb_count1;
        !           270:     int64_t tb_count;
        !           271:     int64_t op_count; /* total insn count */
        !           272:     int op_count_max; /* max insn per TB */
        !           273:     int64_t temp_count;
        !           274:     int temp_count_max;
        !           275:     int64_t del_op_count;
        !           276:     int64_t code_in_len;
        !           277:     int64_t code_out_len;
        !           278:     int64_t interm_time;
        !           279:     int64_t code_time;
        !           280:     int64_t la_time;
        !           281:     int64_t restore_count;
        !           282:     int64_t restore_time;
        !           283: #endif
        !           284: };
        !           285: 
        !           286: extern TCGContext tcg_ctx;
        !           287: extern uint16_t *gen_opc_ptr;
        !           288: extern TCGArg *gen_opparam_ptr;
        !           289: extern uint16_t gen_opc_buf[];
        !           290: extern TCGArg gen_opparam_buf[];
        !           291: 
        !           292: /* pool based memory allocation */
        !           293: 
        !           294: void *tcg_malloc_internal(TCGContext *s, int size);
        !           295: void tcg_pool_reset(TCGContext *s);
        !           296: void tcg_pool_delete(TCGContext *s);
        !           297: 
        !           298: static inline void *tcg_malloc(int size)
        !           299: {
        !           300:     TCGContext *s = &tcg_ctx;
        !           301:     uint8_t *ptr, *ptr_end;
        !           302:     size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
        !           303:     ptr = s->pool_cur;
        !           304:     ptr_end = ptr + size;
        !           305:     if (unlikely(ptr_end > s->pool_end)) {
        !           306:         return tcg_malloc_internal(&tcg_ctx, size);
        !           307:     } else {
        !           308:         s->pool_cur = ptr_end;
        !           309:         return ptr;
        !           310:     }
        !           311: }
        !           312: 
        !           313: void tcg_context_init(TCGContext *s);
        !           314: void tcg_func_start(TCGContext *s);
        !           315: 
        !           316: int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
        !           317: int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
        !           318: 
        !           319: void tcg_set_frame(TCGContext *s, int reg,
        !           320:                    tcg_target_long start, tcg_target_long size);
        !           321: 
        !           322: TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
        !           323: TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
        !           324:                                 const char *name);
        !           325: TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
        !           326: static inline TCGv_i32 tcg_temp_new_i32(void)
        !           327: {
        !           328:     return tcg_temp_new_internal_i32(0);
        !           329: }
        !           330: static inline TCGv_i32 tcg_temp_local_new_i32(void)
        !           331: {
        !           332:     return tcg_temp_new_internal_i32(1);
        !           333: }
        !           334: void tcg_temp_free_i32(TCGv_i32 arg);
        !           335: char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
        !           336: 
        !           337: TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
        !           338: TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
        !           339:                                 const char *name);
        !           340: TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
        !           341: static inline TCGv_i64 tcg_temp_new_i64(void)
        !           342: {
        !           343:     return tcg_temp_new_internal_i64(0);
        !           344: }
        !           345: static inline TCGv_i64 tcg_temp_local_new_i64(void)
        !           346: {
        !           347:     return tcg_temp_new_internal_i64(1);
        !           348: }
        !           349: void tcg_temp_free_i64(TCGv_i64 arg);
        !           350: char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
        !           351: 
        !           352: void tcg_dump_info(FILE *f,
        !           353:                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
        !           354: 
        !           355: #define TCG_CT_ALIAS  0x80
        !           356: #define TCG_CT_IALIAS 0x40
        !           357: #define TCG_CT_REG    0x01
        !           358: #define TCG_CT_CONST  0x02 /* any constant of register size */
        !           359: 
        !           360: typedef struct TCGArgConstraint {
        !           361:     uint16_t ct;
        !           362:     uint8_t alias_index;
        !           363:     union {
        !           364:         TCGRegSet regs;
        !           365:     } u;
        !           366: } TCGArgConstraint;
        !           367: 
        !           368: #define TCG_MAX_OP_ARGS 16
        !           369: 
        !           370: #define TCG_OPF_BB_END     0x01 /* instruction defines the end of a basic
        !           371:                                    block */
        !           372: #define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers 
        !           373:                                    and potentially update globals. */
        !           374: #define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it
        !           375:                                      cannot be removed if its output
        !           376:                                      are not used */
        !           377: 
        !           378: typedef struct TCGOpDef {
        !           379:     const char *name;
        !           380:     uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
        !           381:     uint8_t flags;
        !           382:     uint16_t copy_size;
        !           383:     TCGArgConstraint *args_ct;
        !           384:     int *sorted_args;
        !           385: } TCGOpDef;
        !           386:         
        !           387: typedef struct TCGTargetOpDef {
        !           388:     int op;
        !           389:     const char *args_ct_str[TCG_MAX_OP_ARGS];
        !           390: } TCGTargetOpDef;
        !           391: 
        !           392: void tcg_target_init(TCGContext *s);
        !           393: void tcg_target_qemu_prologue(TCGContext *s);
        !           394: 
        !           395: #define tcg_abort() \
        !           396: do {\
        !           397:     fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
        !           398:     abort();\
        !           399: } while (0)
        !           400: 
        !           401: void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
        !           402: 
        !           403: #if TCG_TARGET_REG_BITS == 32
        !           404: #define tcg_const_ptr tcg_const_i32
        !           405: #define tcg_add_ptr tcg_add_i32
        !           406: #define tcg_sub_ptr tcg_sub_i32
        !           407: #define TCGv_ptr TCGv_i32
        !           408: #define GET_TCGV_PTR GET_TCGV_I32
        !           409: #define tcg_global_reg_new_ptr tcg_global_reg_new_i32
        !           410: #define tcg_global_mem_new_ptr tcg_global_mem_new_i32
        !           411: #define tcg_temp_new_ptr tcg_temp_new_i32
        !           412: #define tcg_temp_free_ptr tcg_temp_free_i32
        !           413: #else
        !           414: #define tcg_const_ptr tcg_const_i64
        !           415: #define tcg_add_ptr tcg_add_i64
        !           416: #define tcg_sub_ptr tcg_sub_i64
        !           417: #define TCGv_ptr TCGv_i64
        !           418: #define GET_TCGV_PTR GET_TCGV_I64
        !           419: #define tcg_global_reg_new_ptr tcg_global_reg_new_i64
        !           420: #define tcg_global_mem_new_ptr tcg_global_mem_new_i64
        !           421: #define tcg_temp_new_ptr tcg_temp_new_i64
        !           422: #define tcg_temp_free_ptr tcg_temp_free_i64
        !           423: #endif
        !           424: 
        !           425: void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
        !           426:                    int sizemask, TCGArg ret, int nargs, TCGArg *args);
        !           427: 
        !           428: void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
        !           429:                         int c, int right, int arith);
        !           430: 
        !           431: /* only used for debugging purposes */
        !           432: void tcg_register_helper(void *func, const char *name);
        !           433: const char *tcg_helper_get_name(TCGContext *s, void *func);
        !           434: void tcg_dump_ops(TCGContext *s, FILE *outfile);
        !           435: 
        !           436: void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
        !           437: TCGv_i32 tcg_const_i32(int32_t val);
        !           438: TCGv_i64 tcg_const_i64(int64_t val);
        !           439: TCGv_i32 tcg_const_local_i32(int32_t val);
        !           440: TCGv_i64 tcg_const_local_i64(int64_t val);
        !           441: 
        !           442: void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, 
        !           443:                    int label_index, long addend);
        !           444: const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
        !           445:                               unsigned int dead_iargs);
        !           446: 
        !           447: /* tcg-runtime.c */
        !           448: int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
        !           449: int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
        !           450: int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
        !           451: int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
        !           452: int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
        !           453: uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
        !           454: uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);
        !           455: 
        !           456: extern uint8_t code_gen_prologue[];
        !           457: #if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
        !           458: #define tcg_qemu_tb_exec(tb_ptr) \
        !           459:     ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
        !           460: #else
        !           461: #define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
        !           462: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.