Loading tcg/i386/tcg-target.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ enum { /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_ESP #define TCG_TARGET_STACK_ALIGN 16 #define TCG_TARGET_CALL_STACK_OFFSET 0 /* Note: must be synced with dyngen-exec.h */ #define TCG_AREG0 TCG_REG_EBP Loading tcg/tcg.c +69 −42 Original line number Diff line number Diff line Loading @@ -560,7 +560,9 @@ static void tcg_gen_call_internal(TCGContext *s, TCGv func, #if TCG_TARGET_REG_BITS < 64 /* Note: we convert the 64 bit args to 32 bit */ /* Note: we convert the 64 bit args to 32 bit and do some alignment and endian swap. Maybe it would be better to do the alignment and endian swap in tcg_reg_alloc_call(). */ void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags, unsigned int nb_rets, const TCGv *rets, unsigned int nb_params, const TCGv *args1) Loading @@ -572,12 +574,17 @@ void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags, ret = rets[0]; if (tcg_get_base_type(s, ret) == TCG_TYPE_I64) { nb_rets = 2; #ifdef TCG_TARGET_WORDS_BIGENDIAN rets_2[0] = TCGV_HIGH(ret); rets_2[1] = ret; #else rets_2[0] = ret; rets_2[1] = TCGV_HIGH(ret); #endif rets = rets_2; } } args2 = alloca((nb_params * 2) * sizeof(TCGv)); args2 = alloca((nb_params * 3) * sizeof(TCGv)); j = 0; call_type = (flags & TCG_CALL_TYPE_MASK); for(i = 0; i < nb_params; i++) { Loading @@ -593,6 +600,12 @@ void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags, args2[j++] = arg; args2[j++] = TCGV_HIGH(arg); #else #ifdef TCG_TARGET_CALL_ALIGN_ARGS /* some targets want aligned 64 bit args */ if (j & 1) { args2[j++] = TCG_CALL_DUMMY_ARG; } #endif #ifdef TCG_TARGET_WORDS_BIGENDIAN args2[j++] = TCGV_HIGH(arg); args2[j++] = arg; Loading Loading @@ -744,9 +757,13 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) } for(i = 0; i < (nb_iargs - 1); i++) { fprintf(outfile, ","); if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) { fprintf(outfile, "<dummy>"); } else { fprintf(outfile, "%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i])); } } } else { if (c == INDEX_op_nopn) { /* variable number of arguments */ Loading Loading @@ -983,11 +1000,13 @@ void tcg_liveness_analysis(TCGContext *s) dead_iargs = 0; for(i = 0; i < nb_iargs; i++) { arg = args[i + nb_oargs]; if (arg != TCG_CALL_DUMMY_ARG) { if (dead_temps[arg]) { dead_iargs |= (1 << i); } dead_temps[arg] = 0; } } s->op_dead_iargs[op_index] = dead_iargs; } args--; Loading Loading @@ -1586,10 +1605,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, if (allocate_args) { tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size)); } /* XXX: on some architectures it does not start at zero */ stack_offset = 0; stack_offset = TCG_TARGET_CALL_STACK_OFFSET; for(i = nb_regs; i < nb_params; i++) { arg = args[nb_oargs + i]; #ifdef TCG_TARGET_STACK_GROWSUP stack_offset -= sizeof(tcg_target_long); #endif if (arg != TCG_CALL_DUMMY_ARG) { ts = &s->temps[arg]; if (ts->val_type == TEMP_VAL_REG) { tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset); Loading @@ -1608,14 +1631,17 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, } else { tcg_abort(); } /* XXX: not necessarily in the same order */ stack_offset += STACK_DIR(sizeof(tcg_target_long)); } #ifndef TCG_TARGET_STACK_GROWSUP stack_offset += sizeof(tcg_target_long); #endif } /* assign input registers */ tcg_regset_set(allocated_regs, s->reserved_regs); for(i = 0; i < nb_regs; i++) { arg = args[nb_oargs + i]; if (arg != TCG_CALL_DUMMY_ARG) { ts = &s->temps[arg]; reg = tcg_target_call_iarg_regs[i]; tcg_reg_free(s, reg); Loading @@ -1633,6 +1659,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, } tcg_regset_set_reg(allocated_regs, reg); } } /* assign function address */ func_arg = args[nb_oargs + nb_iargs - 1]; Loading tcg/tcg.h +4 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,10 @@ typedef int TCGv; safely suppressed if the return value is not used. */ #define TCG_CALL_PURE 0x0010 /* used to align parameters */ #define TCG_CALL_DUMMY_TCGV MAKE_TCGV(-1) #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1)) typedef enum { TCG_COND_EQ, TCG_COND_NE, Loading tcg/x86_64/tcg-target.h +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ enum { /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_RSP #define TCG_TARGET_STACK_ALIGN 16 #define TCG_TARGET_CALL_STACK_OFFSET 0 /* optional instructions */ #define TCG_TARGET_HAS_bswap_i32 Loading Loading
tcg/i386/tcg-target.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ enum { /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_ESP #define TCG_TARGET_STACK_ALIGN 16 #define TCG_TARGET_CALL_STACK_OFFSET 0 /* Note: must be synced with dyngen-exec.h */ #define TCG_AREG0 TCG_REG_EBP Loading
tcg/tcg.c +69 −42 Original line number Diff line number Diff line Loading @@ -560,7 +560,9 @@ static void tcg_gen_call_internal(TCGContext *s, TCGv func, #if TCG_TARGET_REG_BITS < 64 /* Note: we convert the 64 bit args to 32 bit */ /* Note: we convert the 64 bit args to 32 bit and do some alignment and endian swap. Maybe it would be better to do the alignment and endian swap in tcg_reg_alloc_call(). */ void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags, unsigned int nb_rets, const TCGv *rets, unsigned int nb_params, const TCGv *args1) Loading @@ -572,12 +574,17 @@ void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags, ret = rets[0]; if (tcg_get_base_type(s, ret) == TCG_TYPE_I64) { nb_rets = 2; #ifdef TCG_TARGET_WORDS_BIGENDIAN rets_2[0] = TCGV_HIGH(ret); rets_2[1] = ret; #else rets_2[0] = ret; rets_2[1] = TCGV_HIGH(ret); #endif rets = rets_2; } } args2 = alloca((nb_params * 2) * sizeof(TCGv)); args2 = alloca((nb_params * 3) * sizeof(TCGv)); j = 0; call_type = (flags & TCG_CALL_TYPE_MASK); for(i = 0; i < nb_params; i++) { Loading @@ -593,6 +600,12 @@ void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags, args2[j++] = arg; args2[j++] = TCGV_HIGH(arg); #else #ifdef TCG_TARGET_CALL_ALIGN_ARGS /* some targets want aligned 64 bit args */ if (j & 1) { args2[j++] = TCG_CALL_DUMMY_ARG; } #endif #ifdef TCG_TARGET_WORDS_BIGENDIAN args2[j++] = TCGV_HIGH(arg); args2[j++] = arg; Loading Loading @@ -744,9 +757,13 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) } for(i = 0; i < (nb_iargs - 1); i++) { fprintf(outfile, ","); if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) { fprintf(outfile, "<dummy>"); } else { fprintf(outfile, "%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i])); } } } else { if (c == INDEX_op_nopn) { /* variable number of arguments */ Loading Loading @@ -983,11 +1000,13 @@ void tcg_liveness_analysis(TCGContext *s) dead_iargs = 0; for(i = 0; i < nb_iargs; i++) { arg = args[i + nb_oargs]; if (arg != TCG_CALL_DUMMY_ARG) { if (dead_temps[arg]) { dead_iargs |= (1 << i); } dead_temps[arg] = 0; } } s->op_dead_iargs[op_index] = dead_iargs; } args--; Loading Loading @@ -1586,10 +1605,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, if (allocate_args) { tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size)); } /* XXX: on some architectures it does not start at zero */ stack_offset = 0; stack_offset = TCG_TARGET_CALL_STACK_OFFSET; for(i = nb_regs; i < nb_params; i++) { arg = args[nb_oargs + i]; #ifdef TCG_TARGET_STACK_GROWSUP stack_offset -= sizeof(tcg_target_long); #endif if (arg != TCG_CALL_DUMMY_ARG) { ts = &s->temps[arg]; if (ts->val_type == TEMP_VAL_REG) { tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset); Loading @@ -1608,14 +1631,17 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, } else { tcg_abort(); } /* XXX: not necessarily in the same order */ stack_offset += STACK_DIR(sizeof(tcg_target_long)); } #ifndef TCG_TARGET_STACK_GROWSUP stack_offset += sizeof(tcg_target_long); #endif } /* assign input registers */ tcg_regset_set(allocated_regs, s->reserved_regs); for(i = 0; i < nb_regs; i++) { arg = args[nb_oargs + i]; if (arg != TCG_CALL_DUMMY_ARG) { ts = &s->temps[arg]; reg = tcg_target_call_iarg_regs[i]; tcg_reg_free(s, reg); Loading @@ -1633,6 +1659,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, } tcg_regset_set_reg(allocated_regs, reg); } } /* assign function address */ func_arg = args[nb_oargs + nb_iargs - 1]; Loading
tcg/tcg.h +4 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,10 @@ typedef int TCGv; safely suppressed if the return value is not used. */ #define TCG_CALL_PURE 0x0010 /* used to align parameters */ #define TCG_CALL_DUMMY_TCGV MAKE_TCGV(-1) #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1)) typedef enum { TCG_COND_EQ, TCG_COND_NE, Loading
tcg/x86_64/tcg-target.h +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ enum { /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_RSP #define TCG_TARGET_STACK_ALIGN 16 #define TCG_TARGET_CALL_STACK_OFFSET 0 /* optional instructions */ #define TCG_TARGET_HAS_bswap_i32 Loading