From 03271524b66dfc979cc0412bdb5d8d617426b644 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 14 Aug 2013 14:35:56 -0700 Subject: [PATCH 01/29] tcg: Add muluh and mulsh opcodes Use them in places where mulu2 and muls2 are used. Optimize mulx2 with dead low part to mulxh. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.h | 4 ++++ tcg/arm/tcg-target.h | 2 ++ tcg/hppa/tcg-target.h | 2 ++ tcg/i386/tcg-target.h | 4 ++++ tcg/ia64/tcg-target.h | 4 ++++ tcg/mips/tcg-target.h | 2 ++ tcg/optimize.c | 20 ++++++++++++++++++++ tcg/ppc/tcg-target.h | 2 ++ tcg/ppc64/tcg-target.h | 4 ++++ tcg/s390/tcg-target.h | 4 ++++ tcg/sparc/tcg-target.h | 4 ++++ tcg/tcg-op.h | 40 ++++++++++++++++++++++++++++++++++++---- tcg/tcg-opc.h | 4 ++++ tcg/tcg.c | 36 ++++++++++++++++++++++++++++++------ tcg/tcg.h | 2 ++ tcg/tci/tcg-target.h | 5 ++++- 16 files changed, 128 insertions(+), 11 deletions(-) diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index 51e50920b2..26ee28b12c 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -61,6 +61,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i32 0 #define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_muls2_i32 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_div_i64 0 #define TCG_TARGET_HAS_rem_i64 0 @@ -87,6 +89,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i64 0 #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muls2_i64 0 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i64 0 enum { TCG_AREG0 = TCG_REG_X19, diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 5cd9d6a679..ed48092431 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -80,6 +80,8 @@ extern bool use_idiv_instructions; #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_i32 1 #define TCG_TARGET_HAS_muls2_i32 1 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_div_i32 use_idiv_instructions #define TCG_TARGET_HAS_rem_i32 0 diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h index 25467bdd43..0f6f2ff35d 100644 --- a/tcg/hppa/tcg-target.h +++ b/tcg/hppa/tcg-target.h @@ -100,6 +100,8 @@ typedef enum { #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_i32 1 #define TCG_TARGET_HAS_muls2_i32 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 /* optional instructions automatically implemented */ #define TCG_TARGET_HAS_neg_i32 0 /* sub rd, 0, rs */ diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index e3f6bb965f..b7d1a555bb 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -96,6 +96,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i32 1 #define TCG_TARGET_HAS_mulu2_i32 1 #define TCG_TARGET_HAS_muls2_i32 1 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_div2_i64 1 @@ -122,6 +124,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i64 1 #define TCG_TARGET_HAS_mulu2_i64 1 #define TCG_TARGET_HAS_muls2_i64 1 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i64 0 #endif #define TCG_TARGET_deposit_i32_valid(ofs, len) \ diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h index f32d5199cb..ee6b2c8a24 100644 --- a/tcg/ia64/tcg-target.h +++ b/tcg/ia64/tcg-target.h @@ -146,6 +146,10 @@ typedef enum { #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muls2_i32 0 #define TCG_TARGET_HAS_muls2_i64 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i32 0 +#define TCG_TARGET_HAS_mulsh_i64 0 #define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) <= 16) #define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) <= 16) diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index a438950bc1..6cb7c2f3c4 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -89,6 +89,8 @@ typedef enum { #define TCG_TARGET_HAS_eqv_i32 0 #define TCG_TARGET_HAS_nand_i32 0 #define TCG_TARGET_HAS_muls2_i32 1 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 /* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */ #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \ diff --git a/tcg/optimize.c b/tcg/optimize.c index b35868afbc..e8dedf3eb4 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -198,6 +198,8 @@ static TCGOpcode op_to_mov(TCGOpcode op) static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) { + uint64_t l64, h64; + switch (op) { CASE_OP_32_64(add): return x + y; @@ -290,6 +292,18 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) case INDEX_op_ext32u_i64: return (uint32_t)x; + case INDEX_op_muluh_i32: + return ((uint64_t)(uint32_t)x * (uint32_t)y) >> 32; + case INDEX_op_mulsh_i32: + return ((int64_t)(int32_t)x * (int32_t)y) >> 32; + + case INDEX_op_muluh_i64: + mulu64(&l64, &h64, x, y); + return h64; + case INDEX_op_mulsh_i64: + muls64(&l64, &h64, x, y); + return h64; + default: fprintf(stderr, "Unrecognized operation %d in do_constant_folding.\n", op); @@ -531,6 +545,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, CASE_OP_32_64(eqv): CASE_OP_32_64(nand): CASE_OP_32_64(nor): + CASE_OP_32_64(muluh): + CASE_OP_32_64(mulsh): swap_commutative(args[0], &args[1], &args[2]); break; CASE_OP_32_64(brcond): @@ -771,6 +787,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, switch (op) { CASE_OP_32_64(and): CASE_OP_32_64(mul): + CASE_OP_32_64(muluh): + CASE_OP_32_64(mulsh): if ((temps[args[2]].state == TCG_TEMP_CONST && temps[args[2]].val == 0)) { s->gen_opc_buf[op_index] = op_to_movi(op); @@ -882,6 +900,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, CASE_OP_32_64(eqv): CASE_OP_32_64(nand): CASE_OP_32_64(nor): + CASE_OP_32_64(muluh): + CASE_OP_32_64(mulsh): if (temps[args[1]].state == TCG_TEMP_CONST && temps[args[2]].state == TCG_TEMP_CONST) { s->gen_opc_buf[op_index] = op_to_movi(op); diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index b42d97cc24..613c5ff4fc 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -96,6 +96,8 @@ typedef enum { #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_i32 1 #define TCG_TARGET_HAS_muls2_i32 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_AREG0 TCG_REG_R27 diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h index 48fc6e2e54..0789daff83 100644 --- a/tcg/ppc64/tcg-target.h +++ b/tcg/ppc64/tcg-target.h @@ -95,6 +95,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i32 0 #define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_muls2_i32 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_div_i64 1 #define TCG_TARGET_HAS_rem_i64 0 @@ -118,6 +120,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i64 1 #define TCG_TARGET_HAS_mulu2_i64 1 #define TCG_TARGET_HAS_muls2_i64 1 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i64 0 #define TCG_AREG0 TCG_REG_R27 diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index 42ca36c0e9..b02f170d83 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -69,6 +69,8 @@ typedef enum TCGReg { #define TCG_TARGET_HAS_sub2_i32 1 #define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_muls2_i32 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_div2_i64 1 #define TCG_TARGET_HAS_rot_i64 1 @@ -94,6 +96,8 @@ typedef enum TCGReg { #define TCG_TARGET_HAS_sub2_i64 1 #define TCG_TARGET_HAS_mulu2_i64 1 #define TCG_TARGET_HAS_muls2_i64 0 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i64 0 extern bool tcg_target_deposit_valid(int ofs, int len); #define TCG_TARGET_deposit_i32_valid tcg_target_deposit_valid diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index dab52d7176..1a696bc97a 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -107,6 +107,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i32 1 #define TCG_TARGET_HAS_mulu2_i32 1 #define TCG_TARGET_HAS_muls2_i32 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_div_i64 1 @@ -134,6 +136,8 @@ typedef enum { #define TCG_TARGET_HAS_sub2_i64 0 #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muls2_i64 0 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i64 0 #endif #define TCG_AREG0 TCG_REG_I0 diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 364964d8d4..3de7545a46 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -1039,10 +1039,18 @@ static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i32(); - tcg_gen_op4_i32(INDEX_op_mulu2_i32, TCGV_LOW(t0), TCGV_HIGH(t0), - TCGV_LOW(arg1), TCGV_LOW(arg2)); - /* Allow the optimizer room to replace mulu2 with two moves. */ - tcg_gen_op0(INDEX_op_nop); + if (TCG_TARGET_HAS_mulu2_i32) { + tcg_gen_op4_i32(INDEX_op_mulu2_i32, TCGV_LOW(t0), TCGV_HIGH(t0), + TCGV_LOW(arg1), TCGV_LOW(arg2)); + /* Allow the optimizer room to replace mulu2 with two moves. */ + tcg_gen_op0(INDEX_op_nop); + } else { + tcg_debug_assert(TCG_TARGET_HAS_muluh_i32); + tcg_gen_op3_i32(INDEX_op_mul_i32, TCGV_LOW(t0), + TCGV_LOW(arg1), TCGV_LOW(arg2)); + tcg_gen_op3_i32(INDEX_op_muluh_i32, TCGV_HIGH(t0), + TCGV_LOW(arg1), TCGV_LOW(arg2)); + } tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2)); tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); @@ -2401,6 +2409,12 @@ static inline void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2); /* Allow the optimizer room to replace mulu2 with two moves. */ tcg_gen_op0(INDEX_op_nop); + } else if (TCG_TARGET_HAS_muluh_i32) { + TCGv_i32 t = tcg_temp_new_i32(); + tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); + tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2); + tcg_gen_mov_i32(rl, t); + tcg_temp_free_i32(t); } else { TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t1 = tcg_temp_new_i64(); @@ -2420,6 +2434,12 @@ static inline void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2); /* Allow the optimizer room to replace muls2 with two moves. */ tcg_gen_op0(INDEX_op_nop); + } else if (TCG_TARGET_HAS_mulsh_i32) { + TCGv_i32 t = tcg_temp_new_i32(); + tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); + tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2); + tcg_gen_mov_i32(rl, t); + tcg_temp_free_i32(t); } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_mulu2_i32) { TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32(); @@ -2499,6 +2519,12 @@ static inline void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2); /* Allow the optimizer room to replace mulu2 with two moves. */ tcg_gen_op0(INDEX_op_nop); + } else if (TCG_TARGET_HAS_muluh_i64) { + TCGv_i64 t = tcg_temp_new_i64(); + tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); + tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2); + tcg_gen_mov_i64(rl, t); + tcg_temp_free_i64(t); } else if (TCG_TARGET_HAS_mulu2_i64) { TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t1 = tcg_temp_new_i64(); @@ -2540,6 +2566,12 @@ static inline void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2); /* Allow the optimizer room to replace muls2 with two moves. */ tcg_gen_op0(INDEX_op_nop); + } else if (TCG_TARGET_HAS_mulsh_i64) { + TCGv_i64 t = tcg_temp_new_i64(); + tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); + tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2); + tcg_gen_mov_i64(rl, t); + tcg_temp_free_i64(t); } else { TCGv_i64 t0 = tcg_temp_new_i64(); int sizemask = 0; diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index a8af5b96a4..a75c29d518 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -91,6 +91,8 @@ DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_add2_i32)) DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32)) DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32)) DEF(muls2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_muls2_i32)) +DEF(muluh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i32)) +DEF(mulsh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i32)) DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | IMPL(TCG_TARGET_REG_BITS == 32)) DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32)) @@ -167,6 +169,8 @@ DEF(add2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_add2_i64)) DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64)) DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64)) DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64)) +DEF(muluh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i64)) +DEF(mulsh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i64)) /* QEMU specific */ #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS diff --git a/tcg/tcg.c b/tcg/tcg.c index 19bd5a39bf..541a442517 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1252,12 +1252,13 @@ static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps, static void tcg_liveness_analysis(TCGContext *s) { int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops; - TCGOpcode op, op_new; + TCGOpcode op, op_new, op_new2; TCGArg *args; const TCGOpDef *def; uint8_t *dead_temps, *mem_temps; uint16_t dead_args; uint8_t sync_args; + bool have_op_new2; s->gen_opc_ptr++; /* skip end */ @@ -1394,29 +1395,52 @@ static void tcg_liveness_analysis(TCGContext *s) goto do_not_remove; case INDEX_op_mulu2_i32: + op_new = INDEX_op_mul_i32; + op_new2 = INDEX_op_muluh_i32; + have_op_new2 = TCG_TARGET_HAS_muluh_i32; + goto do_mul2; case INDEX_op_muls2_i32: op_new = INDEX_op_mul_i32; + op_new2 = INDEX_op_mulsh_i32; + have_op_new2 = TCG_TARGET_HAS_mulsh_i32; goto do_mul2; case INDEX_op_mulu2_i64: + op_new = INDEX_op_mul_i64; + op_new2 = INDEX_op_muluh_i64; + have_op_new2 = TCG_TARGET_HAS_muluh_i64; + goto do_mul2; case INDEX_op_muls2_i64: op_new = INDEX_op_mul_i64; + op_new2 = INDEX_op_mulsh_i64; + have_op_new2 = TCG_TARGET_HAS_mulsh_i64; + goto do_mul2; do_mul2: args -= 4; nb_iargs = 2; nb_oargs = 2; - /* Likewise, test for the high part of the operation dead. */ if (dead_temps[args[1]] && !mem_temps[args[1]]) { if (dead_temps[args[0]] && !mem_temps[args[0]]) { + /* Both parts of the operation are dead. */ goto do_remove; } + /* The high part of the operation is dead; generate the low. */ s->gen_opc_buf[op_index] = op = op_new; args[1] = args[2]; args[2] = args[3]; - assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop); - tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1); - /* Fall through and mark the single-word operation live. */ - nb_oargs = 1; + } else if (have_op_new2 && dead_temps[args[0]] + && !mem_temps[args[0]]) { + /* The low part of the operation is dead; generate the high. */ + s->gen_opc_buf[op_index] = op = op_new2; + args[0] = args[1]; + args[1] = args[2]; + args[2] = args[3]; + } else { + goto do_not_remove; } + assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop); + tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1); + /* Mark the single-word operation live. */ + nb_oargs = 1; goto do_not_remove; default: diff --git a/tcg/tcg.h b/tcg/tcg.h index f3f9889694..3f869dd9b0 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -85,6 +85,8 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_sub2_i64 0 #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muls2_i64 0 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i64 0 /* Turn some undef macros into true macros. */ #define TCG_TARGET_HAS_add2_i32 1 #define TCG_TARGET_HAS_sub2_i32 1 diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index d7fc14eb17..ff12b4b9c7 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -76,6 +76,8 @@ #define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_movcond_i32 0 #define TCG_TARGET_HAS_muls2_i32 0 +#define TCG_TARGET_HAS_muluh_i32 0 +#define TCG_TARGET_HAS_mulsh_i32 0 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_bswap16_i64 1 @@ -100,13 +102,14 @@ #define TCG_TARGET_HAS_rot_i64 1 #define TCG_TARGET_HAS_movcond_i64 0 #define TCG_TARGET_HAS_muls2_i64 0 - #define TCG_TARGET_HAS_add2_i32 0 #define TCG_TARGET_HAS_sub2_i32 0 #define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_add2_i64 0 #define TCG_TARGET_HAS_sub2_i64 0 #define TCG_TARGET_HAS_mulu2_i64 0 +#define TCG_TARGET_HAS_muluh_i64 0 +#define TCG_TARGET_HAS_mulsh_i64 0 #endif /* TCG_TARGET_REG_BITS == 64 */ /* Number of registers available. From 3c9a8f17560794ad23889318cc42894c6e592cc3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 14 Aug 2013 14:41:43 -0700 Subject: [PATCH 02/29] tcg-mips: Implement mulsh, muluh With the optimization in tcg_liveness_analysis, we can avoid the MFLO when it is unused. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/mips/tcg-target.c | 10 ++++++++++ tcg/mips/tcg-target.h | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 793532ec95..31cd514167 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -1423,6 +1423,14 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0); tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0); break; + case INDEX_op_mulsh_i32: + tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]); + tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0); + break; + case INDEX_op_muluh_i32: + tcg_out_opc_reg(s, OPC_MULTU, 0, args[1], args[2]); + tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0); + break; case INDEX_op_div_i32: tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]); tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0); @@ -1602,6 +1610,8 @@ static const TCGTargetOpDef mips_op_defs[] = { { INDEX_op_mul_i32, { "r", "rZ", "rZ" } }, { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } }, { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } }, + { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } }, + { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } }, { INDEX_op_div_i32, { "r", "rZ", "rZ" } }, { INDEX_op_divu_i32, { "r", "rZ", "rZ" } }, { INDEX_op_rem_i32, { "r", "rZ", "rZ" } }, diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index 6cb7c2f3c4..7ef79e0879 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -89,8 +89,8 @@ typedef enum { #define TCG_TARGET_HAS_eqv_i32 0 #define TCG_TARGET_HAS_nand_i32 0 #define TCG_TARGET_HAS_muls2_i32 1 -#define TCG_TARGET_HAS_muluh_i32 0 -#define TCG_TARGET_HAS_mulsh_i32 0 +#define TCG_TARGET_HAS_muluh_i32 1 +#define TCG_TARGET_HAS_mulsh_i32 1 /* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */ #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \ From 32f5717f07e5f801e482052311d21a4223fc78f1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 14 Aug 2013 14:46:08 -0700 Subject: [PATCH 03/29] tcg-ppc64: Implement muluh, mulsh Using these instead of mulu2 and muls2 lets us avoid having to argument overlap analysis in the backend. Normal register allocation will DTRT. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 32 +++++++------------------------- tcg/ppc64/tcg-target.h | 8 ++++---- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 0678de2045..939f7cb318 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -1975,29 +1975,11 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, } break; - case INDEX_op_mulu2_i64: - case INDEX_op_muls2_i64: - { - int oph = (opc == INDEX_op_mulu2_i64 ? MULHDU : MULHD); - TCGReg outl = args[0], outh = args[1]; - a0 = args[2], a1 = args[3]; - - if (outl == a0 || outl == a1) { - if (outh == a0 || outh == a1) { - outl = TCG_REG_R0; - } else { - tcg_out32(s, oph | TAB(outh, a0, a1)); - oph = 0; - } - } - tcg_out32(s, MULLD | TAB(outl, a0, a1)); - if (oph != 0) { - tcg_out32(s, oph | TAB(outh, a0, a1)); - } - if (outl != args[0]) { - tcg_out_mov(s, TCG_TYPE_I64, args[0], outl); - } - } + case INDEX_op_muluh_i64: + tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2])); + break; + case INDEX_op_mulsh_i64: + tcg_out32(s, MULHD | TAB(args[0], args[1], args[2])); break; default: @@ -2124,8 +2106,8 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } }, { INDEX_op_sub2_i64, { "r", "r", "rI", "r", "rZM", "r" } }, - { INDEX_op_muls2_i64, { "r", "r", "r", "r" } }, - { INDEX_op_mulu2_i64, { "r", "r", "r", "r" } }, + { INDEX_op_mulsh_i64, { "r", "r", "r" } }, + { INDEX_op_muluh_i64, { "r", "r", "r" } }, { -1 }, }; diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h index 0789daff83..fa4b9da093 100644 --- a/tcg/ppc64/tcg-target.h +++ b/tcg/ppc64/tcg-target.h @@ -118,10 +118,10 @@ typedef enum { #define TCG_TARGET_HAS_movcond_i64 1 #define TCG_TARGET_HAS_add2_i64 1 #define TCG_TARGET_HAS_sub2_i64 1 -#define TCG_TARGET_HAS_mulu2_i64 1 -#define TCG_TARGET_HAS_muls2_i64 1 -#define TCG_TARGET_HAS_muluh_i64 0 -#define TCG_TARGET_HAS_mulsh_i64 0 +#define TCG_TARGET_HAS_mulu2_i64 0 +#define TCG_TARGET_HAS_muls2_i64 0 +#define TCG_TARGET_HAS_muluh_i64 1 +#define TCG_TARGET_HAS_mulsh_i64 1 #define TCG_AREG0 TCG_REG_R27 From 01547f7f9283e416578323e5d5df3327ed4df3ee Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 14 Aug 2013 15:22:46 -0700 Subject: [PATCH 04/29] tcg: Constant fold div, rem Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/optimize.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tcg/optimize.c b/tcg/optimize.c index e8dedf3eb4..b29bf25b67 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -304,6 +304,25 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) muls64(&l64, &h64, x, y); return h64; + case INDEX_op_div_i32: + /* Avoid crashing on divide by zero, otherwise undefined. */ + return (int32_t)x / ((int32_t)y ? : 1); + case INDEX_op_divu_i32: + return (uint32_t)x / ((uint32_t)y ? : 1); + case INDEX_op_div_i64: + return (int64_t)x / ((int64_t)y ? : 1); + case INDEX_op_divu_i64: + return (uint64_t)x / ((uint64_t)y ? : 1); + + case INDEX_op_rem_i32: + return (int32_t)x % ((int32_t)y ? : 1); + case INDEX_op_remu_i32: + return (uint32_t)x % ((uint32_t)y ? : 1); + case INDEX_op_rem_i64: + return (int64_t)x % ((int64_t)y ? : 1); + case INDEX_op_remu_i64: + return (uint64_t)x % ((uint64_t)y ? : 1); + default: fprintf(stderr, "Unrecognized operation %d in do_constant_folding.\n", op); @@ -902,6 +921,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, CASE_OP_32_64(nor): CASE_OP_32_64(muluh): CASE_OP_32_64(mulsh): + CASE_OP_32_64(div): + CASE_OP_32_64(divu): + CASE_OP_32_64(rem): + CASE_OP_32_64(remu): if (temps[args[1]].state == TCG_TEMP_CONST && temps[args[2]].state == TCG_TEMP_CONST) { s->gen_opc_buf[op_index] = op_to_movi(op); From 35aa3fb38753bd1557af8370994ce6c5b599e65c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 13:53:25 -0700 Subject: [PATCH 05/29] qtest: Fix FMT_timeval vs time_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since FMT_timeval unconditionally uses %ld for both tv_sec and tv_usec, and already casts tv_usec to long, also cast tv_sec to long. Cc: Andreas Färber Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- qtest.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qtest.c b/qtest.c index ef671fb05d..584c70762a 100644 --- a/qtest.c +++ b/qtest.c @@ -177,7 +177,7 @@ static void qtest_send_prefix(CharDriverState *chr) qtest_get_time(&tv); fprintf(qtest_log_fp, "[S +" FMT_timeval "] ", - tv.tv_sec, (long) tv.tv_usec); + (long) tv.tv_sec, (long) tv.tv_usec); } static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr, @@ -225,7 +225,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) qtest_get_time(&tv); fprintf(qtest_log_fp, "[R +" FMT_timeval "]", - tv.tv_sec, (long) tv.tv_usec); + (long) tv.tv_sec, (long) tv.tv_usec); for (i = 0; words[i]; i++) { fprintf(qtest_log_fp, " %s", words[i]); } @@ -485,7 +485,7 @@ static void qtest_event(void *opaque, int event) qtest_opened = true; if (qtest_log_fp) { fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n", - start_time.tv_sec, (long) start_time.tv_usec); + (long) start_time.tv_sec, (long) start_time.tv_usec); } break; case CHR_EVENT_CLOSED: @@ -494,7 +494,7 @@ static void qtest_event(void *opaque, int event) qemu_timeval tv; qtest_get_time(&tv); fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n", - tv.tv_sec, (long) tv.tv_usec); + (long) tv.tv_sec, (long) tv.tv_usec); } break; default: From b93949ef6a5dea2b22987f2aa3028068e751a7e4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 14:22:50 -0700 Subject: [PATCH 06/29] tcg: Change flush_icache_range arguments to uintptr_t Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.h | 3 +-- tcg/arm/tcg-target.h | 9 ++++----- tcg/hppa/tcg-target.h | 3 +-- tcg/i386/tcg-target.h | 3 +-- tcg/ia64/tcg-target.h | 3 +-- tcg/mips/tcg-target.h | 3 +-- tcg/s390/tcg-target.h | 3 +-- tcg/sparc/tcg-target.h | 12 ++++-------- tcg/tcg.c | 6 ++---- tcg/tci/tcg-target.h | 3 +-- 10 files changed, 17 insertions(+), 31 deletions(-) diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index 26ee28b12c..d3a1bc2437 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -96,8 +96,7 @@ enum { TCG_AREG0 = TCG_REG_X19, }; -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { __builtin___clear_cache((char *)start, (char *)stop); } diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index ed48092431..9482bfa993 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -92,15 +92,14 @@ enum { TCG_AREG0 = TCG_REG_R6, }; -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { #if QEMU_GNUC_PREREQ(4, 1) __builtin___clear_cache((char *) start, (char *) stop); #else - register unsigned long _beg __asm ("a1") = start; - register unsigned long _end __asm ("a2") = stop; - register unsigned long _flg __asm ("a3") = 0; + register uintptr_t _beg __asm("a1") = start; + register uintptr_t _end __asm("a2") = stop; + register uintptr_t _flg __asm("a3") = 0; __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg)); #endif } diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h index 0f6f2ff35d..be5895f847 100644 --- a/tcg/hppa/tcg-target.h +++ b/tcg/hppa/tcg-target.h @@ -111,8 +111,7 @@ typedef enum { #define TCG_AREG0 TCG_REG_R17 -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { start &= ~31; while (start <= stop) { diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index b7d1a555bb..1f6c7eb8a5 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -139,8 +139,7 @@ typedef enum { # define TCG_AREG0 TCG_REG_EBP #endif -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { } diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h index ee6b2c8a24..4330c9cdd3 100644 --- a/tcg/ia64/tcg-target.h +++ b/tcg/ia64/tcg-target.h @@ -162,8 +162,7 @@ typedef enum { #define TCG_AREG0 TCG_REG_R7 -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { start = start & ~(32UL - 1UL); stop = (stop + (32UL - 1UL)) & ~(32UL - 1UL); diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index 7ef79e0879..a820328093 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -127,8 +127,7 @@ typedef enum { #include #endif -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { cacheflush ((void *)start, stop-start, ICACHE); } diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index b02f170d83..6142fb26a2 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -114,8 +114,7 @@ enum { TCG_AREG0 = TCG_REG_R10, }; -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { } diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index 1a696bc97a..c0d3abcc7d 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -142,16 +142,12 @@ typedef enum { #define TCG_AREG0 TCG_REG_I0 -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { - unsigned long p; - - p = start & ~(8UL - 1UL); - stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL); - - for (; p < stop; p += 8) + uintptr_t p; + for (p = start & -8; p < (stop + 7) & -8; p += 8) { __asm__ __volatile__("flush\t%0" : : "r" (p)); + } } #endif diff --git a/tcg/tcg.c b/tcg/tcg.c index 541a442517..65cffcae8a 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -293,8 +293,7 @@ void tcg_prologue_init(TCGContext *s) s->code_buf = s->code_gen_prologue; s->code_ptr = s->code_buf; tcg_target_qemu_prologue(s); - flush_icache_range((tcg_target_ulong)s->code_buf, - (tcg_target_ulong)s->code_ptr); + flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr); #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { @@ -2415,8 +2414,7 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf) tcg_gen_code_common(s, gen_code_buf, -1); /* flush instruction cache */ - flush_icache_range((tcg_target_ulong)gen_code_buf, - (tcg_target_ulong)s->code_ptr); + flush_icache_range((uintptr_t)gen_code_buf, (uintptr_t)s->code_ptr); return s->code_ptr - gen_code_buf; } diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index ff12b4b9c7..e284972d92 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -172,8 +172,7 @@ void tci_disas(uint8_t opc); tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr); #define tcg_qemu_tb_exec tcg_qemu_tb_exec -static inline void flush_icache_range(tcg_target_ulong start, - tcg_target_ulong stop) +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { } From 04d5a1da70dfe1a3a5ac5b5a8e7a7b8136d3a985 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 14:35:34 -0700 Subject: [PATCH 07/29] tcg: Change tcg_qemu_tb_exec return to uintptr_t Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- cpu-exec.c | 2 +- tcg/ppc/tcg-target.h | 2 +- tcg/tcg.h | 3 +-- tcg/tci/tcg-target.h | 2 +- tci.c | 4 ++-- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 301be28bf7..14af2edab6 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -53,7 +53,7 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc) static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) { CPUArchState *env = cpu->env_ptr; - tcg_target_ulong next_tb = tcg_qemu_tb_exec(env, tb_ptr); + uintptr_t next_tb = tcg_qemu_tb_exec(env, tb_ptr); if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) { /* We didn't start executing this TB (eg because the instruction * counter hit zero); we must restore the guest PC to the address diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index 613c5ff4fc..c9f8ff5206 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -102,7 +102,7 @@ typedef enum { #define TCG_AREG0 TCG_REG_R27 #define tcg_qemu_tb_exec(env, tb_ptr) \ - ((long __attribute__ ((longcall)) \ + ((uintptr_t __attribute__ ((longcall)) \ (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr) #endif diff --git a/tcg/tcg.h b/tcg/tcg.h index 3f869dd9b0..2fce485abc 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -733,8 +733,7 @@ TCGv_i64 tcg_const_local_i64(int64_t val); #if !defined(tcg_qemu_tb_exec) # define tcg_qemu_tb_exec(env, tb_ptr) \ - ((tcg_target_ulong (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, \ - tb_ptr) + ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr) #endif void tcg_register_jit(void *buf, size_t buf_size); diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index e284972d92..02e0da1304 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -169,7 +169,7 @@ typedef enum { void tci_disas(uint8_t opc); -tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr); +uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr); #define tcg_qemu_tb_exec tcg_qemu_tb_exec static inline void flush_icache_range(uintptr_t start, uintptr_t stop) diff --git a/tci.c b/tci.c index c742c8df5c..18c888e54d 100644 --- a/tci.c +++ b/tci.c @@ -434,11 +434,11 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition) } /* Interpret pseudo code in tb. */ -tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) +uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) { long tcg_temps[CPU_TEMP_BUF_NLONGS]; uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS); - tcg_target_ulong next_tb = 0; + uintptr_t next_tb = 0; tci_reg[TCG_AREG0] = (tcg_target_ulong)env; tci_reg[TCG_REG_CALL_STACK] = sp_value; From 3e9bd63acf145bb2d3da277ee85167878ade53bd Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 14:40:25 -0700 Subject: [PATCH 08/29] tcg: Fix next_tb type in cpu_exec Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- cpu-exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu-exec.c b/cpu-exec.c index 14af2edab6..5a4399509e 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -209,7 +209,7 @@ int cpu_exec(CPUArchState *env) int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; - tcg_target_ulong next_tb; + uintptr_t next_tb; if (cpu->halted) { if (!cpu_has_work(cpu)) { From 78cd7b835e13bee4416782b6ed41e9bef76e3cfc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 14:41:29 -0700 Subject: [PATCH 09/29] tcg: Allow TCG_TARGET_REG_BITS to be specified independantly There are several hosts for which it would be useful to use the available 64-bit registers in a 32-bit pointer environment. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/hppa/tcg-target.c | 4 ++++ tcg/hppa/tcg-target.h | 4 ---- tcg/i386/tcg-target.h | 10 ++++++---- tcg/sparc/tcg-target.h | 8 ++++++++ tcg/tcg.h | 19 +++++++++++-------- tcg/tci/tcg-target.h | 8 ++++++++ 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index 68f77ba4dd..e5aed91987 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -22,6 +22,10 @@ * THE SOFTWARE. */ +#if TCG_TARGET_REG_BITS != 32 +#error unsupported +#endif + #ifndef NDEBUG static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { "%r0", "%r1", "%rp", "%r3", "%r4", "%r5", "%r6", "%r7", diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h index be5895f847..122edce7a7 100644 --- a/tcg/hppa/tcg-target.h +++ b/tcg/hppa/tcg-target.h @@ -25,10 +25,6 @@ #ifndef TCG_TARGET_HPPA #define TCG_TARGET_HPPA 1 -#if TCG_TARGET_REG_BITS != 32 -#error unsupported -#endif - #define TCG_TARGET_WORDS_BIGENDIAN #define TCG_TARGET_NB_REGS 32 diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index 1f6c7eb8a5..d32d7ef6f0 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -24,12 +24,14 @@ #ifndef TCG_TARGET_I386 #define TCG_TARGET_I386 1 -//#define TCG_TARGET_WORDS_BIGENDIAN +#undef TCG_TARGET_WORDS_BIGENDIAN -#if TCG_TARGET_REG_BITS == 64 -# define TCG_TARGET_NB_REGS 16 +#ifdef __x86_64__ +# define TCG_TARGET_REG_BITS 64 +# define TCG_TARGET_NB_REGS 16 #else -# define TCG_TARGET_NB_REGS 8 +# define TCG_TARGET_REG_BITS 32 +# define TCG_TARGET_NB_REGS 8 #endif typedef enum { diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index c0d3abcc7d..2edf858733 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -24,6 +24,14 @@ #ifndef TCG_TARGET_SPARC #define TCG_TARGET_SPARC 1 +#if UINTPTR_MAX == UINT32_MAX +# define TCG_TARGET_REG_BITS 32 +#elif UINTPTR_MAX == UINT64_MAX +# define TCG_TARGET_REG_BITS 64 +#else +# error Unknown pointer size for tcg target +#endif + #define TCG_TARGET_WORDS_BIGENDIAN #define TCG_TARGET_NB_REGS 32 diff --git a/tcg/tcg.h b/tcg/tcg.h index 2fce485abc..8a5e55bcc4 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -23,13 +23,17 @@ */ #include "qemu-common.h" -/* Target word size (must be identical to pointer size). */ -#if UINTPTR_MAX == UINT32_MAX -# define TCG_TARGET_REG_BITS 32 -#elif UINTPTR_MAX == UINT64_MAX -# define TCG_TARGET_REG_BITS 64 -#else -# error Unknown pointer size for tcg target +#include "tcg-target.h" + +/* Default target word size to pointer size. */ +#ifndef TCG_TARGET_REG_BITS +# if UINTPTR_MAX == UINT32_MAX +# define TCG_TARGET_REG_BITS 32 +# elif UINTPTR_MAX == UINT64_MAX +# define TCG_TARGET_REG_BITS 64 +# else +# error Unknown pointer size for tcg target +# endif #endif #if TCG_TARGET_REG_BITS == 32 @@ -46,7 +50,6 @@ typedef uint64_t tcg_target_ulong; #error unsupported #endif -#include "tcg-target.h" #include "tcg-runtime.h" #if TCG_TARGET_NB_REGS <= 32 diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 02e0da1304..c2ecfbe047 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -44,6 +44,14 @@ #define TCG_TARGET_INTERPRETER 1 +#if UINTPTR_MAX == UINT32_MAX +# define TCG_TARGET_REG_BITS 32 +#elif UINTPTR_MAX == UINT64_MAX +# define TCG_TARGET_REG_BITS 64 +#else +# error Unknown pointer size for tci target +#endif + #ifdef CONFIG_DEBUG_TCG /* Enable debug output. */ #define CONFIG_DEBUG_TCG_INTERPRETER From d289837eef3550ac156082d812231ec5dfe79501 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 14:48:46 -0700 Subject: [PATCH 10/29] tcg: Define TCG_TYPE_PTR properly Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/tcg.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tcg/tcg.h b/tcg/tcg.h index 8a5e55bcc4..7a6f2e5f11 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -178,9 +178,12 @@ typedef enum TCGType { TCG_TYPE_REG = TCG_TYPE_I64, #endif - /* An alias for the size of the native pointer. We don't currently - support any hosts with 64-bit registers and 32-bit pointers. */ - TCG_TYPE_PTR = TCG_TYPE_REG, + /* An alias for the size of the native pointer. */ +#if UINTPTR_MAX == UINT32_MAX + TCG_TYPE_PTR = TCG_TYPE_I32, +#else + TCG_TYPE_PTR = TCG_TYPE_I64, +#endif /* An alias for the size of the target "long", aka register. */ #if TARGET_LONG_BITS == 64 From 8b73d49f53e1a1d1571ac783ec028ff27befd93e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 15:07:08 -0700 Subject: [PATCH 11/29] tcg: Define TCG_ptr properly Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/tcg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tcg/tcg.h b/tcg/tcg.h index 7a6f2e5f11..bb215a73e8 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -645,11 +645,11 @@ do {\ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs); -#if TCG_TARGET_REG_BITS == 32 +#if UINTPTR_MAX == UINT32_MAX #define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n)) #define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n)) -#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((tcg_target_long)(V))) +#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V))) #define tcg_global_reg_new_ptr(R, N) \ TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N))) #define tcg_global_mem_new_ptr(R, O, N) \ @@ -660,7 +660,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs); #define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n)) #define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n)) -#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((tcg_target_long)(V))) +#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V))) #define tcg_global_reg_new_ptr(R, N) \ TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N))) #define tcg_global_mem_new_ptr(R, O, N) \ From e2c6d1b42d34539120c3cee159dcd9e32cba7d3b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 15:12:31 -0700 Subject: [PATCH 12/29] tcg: Change frame pointer offsets to intptr_t Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/tcg.c | 5 ++--- tcg/tcg.h | 9 ++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 65cffcae8a..240e6f4a81 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -306,8 +306,7 @@ void tcg_prologue_init(TCGContext *s) #endif } -void tcg_set_frame(TCGContext *s, int reg, - tcg_target_long start, tcg_target_long size) +void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size) { s->frame_start = start; s->frame_end = start + size; @@ -1613,7 +1612,7 @@ static void temp_allocate_frame(TCGContext *s, int temp) ts->mem_offset = s->current_frame_offset; ts->mem_reg = s->frame_reg; ts->mem_allocated = 1; - s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long); + s->current_frame_offset += sizeof(tcg_target_long); } /* sync register 'reg' by saving it to the corresponding temporary */ diff --git a/tcg/tcg.h b/tcg/tcg.h index bb215a73e8..b7e112e534 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -435,9 +435,9 @@ struct TCGContext { into account fixed registers */ int reg_to_temp[TCG_TARGET_NB_REGS]; TCGRegSet reserved_regs; - tcg_target_long current_frame_offset; - tcg_target_long frame_start; - tcg_target_long frame_end; + intptr_t current_frame_offset; + intptr_t frame_start; + intptr_t frame_end; int frame_reg; uint8_t *code_ptr; @@ -530,8 +530,7 @@ void tcg_func_start(TCGContext *s); int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf); int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset); -void tcg_set_frame(TCGContext *s, int reg, - tcg_target_long start, tcg_target_long size); +void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size); TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name); TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset, From 2f2f244d02a2cb28db7ce790576ade08fc3a54bf Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 15:17:25 -0700 Subject: [PATCH 13/29] tcg: Change memory offsets to intptr_t Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/tcg.c | 16 +++++----------- tcg/tcg.h | 8 +++----- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 240e6f4a81..251d39050c 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -389,7 +389,7 @@ TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name) } static inline int tcg_global_mem_new_internal(TCGType type, int reg, - tcg_target_long offset, + intptr_t offset, const char *name) { TCGContext *s = &tcg_ctx; @@ -449,21 +449,15 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg, return idx; } -TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset, - const char *name) +TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name) { - int idx; - - idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name); + int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name); return MAKE_TCGV_I32(idx); } -TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset, - const char *name) +TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name) { - int idx; - - idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name); + int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name); return MAKE_TCGV_I64(idx); } diff --git a/tcg/tcg.h b/tcg/tcg.h index b7e112e534..8fe80692b2 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -388,7 +388,7 @@ typedef struct TCGTemp { int reg; tcg_target_long val; int mem_reg; - tcg_target_long mem_offset; + intptr_t mem_offset; unsigned int fixed_reg:1; unsigned int mem_coherent:1; unsigned int mem_allocated:1; @@ -533,8 +533,7 @@ int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset); void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size); TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name); -TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset, - const char *name); +TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name); TCGv_i32 tcg_temp_new_internal_i32(int temp_local); static inline TCGv_i32 tcg_temp_new_i32(void) { @@ -548,8 +547,7 @@ void tcg_temp_free_i32(TCGv_i32 arg); char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg); TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name); -TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset, - const char *name); +TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name); TCGv_i64 tcg_temp_new_internal_i64(int temp_local); static inline TCGv_i64 tcg_temp_new_i64(void) { From 2ba7fae29ec63acf2ce77d20d4146fa224bf2338 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 15:30:10 -0700 Subject: [PATCH 14/29] tcg: Change relocation offsets to intptr_t Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 2 +- tcg/arm/tcg-target.c | 8 ++++---- tcg/hppa/tcg-target.c | 6 +++--- tcg/i386/tcg-target.c | 2 +- tcg/ia64/tcg-target.c | 14 +++++++------- tcg/mips/tcg-target.c | 16 ++++++++-------- tcg/ppc/tcg-target.c | 2 +- tcg/ppc64/tcg-target.c | 2 +- tcg/s390/tcg-target.c | 6 +++--- tcg/sparc/tcg-target.c | 6 +++--- tcg/tcg.c | 9 +++++---- tcg/tcg.h | 4 ++-- tcg/tci/tcg-target.c | 2 +- 13 files changed, 40 insertions(+), 39 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 41a17f8a62..7dde210303 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -88,7 +88,7 @@ static inline void reloc_pc19(void *code_ptr, tcg_target_long target) } static inline void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { value += addend; diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 6c4854dbb0..e93c67f74d 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -108,21 +108,21 @@ static const int tcg_target_call_oarg_regs[2] = { #define TCG_REG_TMP TCG_REG_R12 -static inline void reloc_abs32(void *code_ptr, tcg_target_long target) +static inline void reloc_abs32(void *code_ptr, intptr_t target) { *(uint32_t *) code_ptr = target; } -static inline void reloc_pc24(void *code_ptr, tcg_target_long target) +static inline void reloc_pc24(void *code_ptr, intptr_t target) { - uint32_t offset = ((target - ((tcg_target_long) code_ptr + 8)) >> 2); + uint32_t offset = ((target - ((intptr_t)code_ptr + 8)) >> 2); *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & ~0xffffff) | (offset & 0xffffff); } static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { switch (type) { case R_ARM_ABS32: diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index e5aed91987..f770250844 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -149,14 +149,14 @@ static int reassemble_21(int as21) #define R_PARISC_PCREL12F R_PARISC_NONE static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { uint32_t *insn_ptr = (uint32_t *)code_ptr; uint32_t insn = *insn_ptr; - tcg_target_long pcrel; + intptr_t pcrel; value += addend; - pcrel = (value - ((tcg_target_long)code_ptr + 8)) >> 2; + pcrel = (value - ((intptr_t)code_ptr + 8)) >> 2; switch (type) { case R_PARISC_PCREL12F: diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 12a7ca3440..031df7163d 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -112,7 +112,7 @@ static bool have_cmov; static uint8_t *tb_ret_addr; static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { value += addend; switch(type) { diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 2373d9ef79..c499ee8bf9 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -668,16 +668,16 @@ static inline uint64_t tcg_opc_x3(int qp, uint64_t opc, uint64_t imm) * Relocations */ -static inline void reloc_pcrel21b (void *pc, tcg_target_long target) +static inline void reloc_pcrel21b(void *pc, intptr_t target) { uint64_t imm; int64_t disp; int slot; - slot = (tcg_target_long) pc & 3; - pc = (void *)((tcg_target_long) pc & ~3); + slot = (intptr_t)pc & 3; + pc = (void *)((intptr_t)pc & ~3); - disp = target - (tcg_target_long) pc; + disp = target - (intptr_t)pc; imm = (uint64_t) disp >> 4; switch(slot) { @@ -728,12 +728,12 @@ static inline uint64_t get_reloc_pcrel21b (void *pc) } } -static inline void reloc_pcrel60b (void *pc, tcg_target_long target) +static inline void reloc_pcrel60b(void *pc, intptr_t target) { int64_t disp; uint64_t imm; - disp = target - (tcg_target_long) pc; + disp = target - (intptr_t)pc; imm = (uint64_t) disp >> 4; *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xf700000fff800000ull) @@ -759,7 +759,7 @@ static inline uint64_t get_reloc_pcrel60b (void *pc) static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { value += addend; switch (type) { diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 31cd514167..f7ea140177 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -108,33 +108,33 @@ static const TCGReg tcg_target_call_oarg_regs[2] = { static uint8_t *tb_ret_addr; -static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target) +static inline uint32_t reloc_lo16_val(void *pc, intptr_t target) { return target & 0xffff; } -static inline void reloc_lo16 (void *pc, tcg_target_long target) +static inline void reloc_lo16(void *pc, intptr_t target) { *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff) | reloc_lo16_val(pc, target); } -static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target) +static inline uint32_t reloc_hi16_val(void *pc, intptr_t target) { return (target >> 16) & 0xffff; } -static inline void reloc_hi16 (void *pc, tcg_target_long target) +static inline void reloc_hi16(void *pc, intptr_t target) { *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff) | reloc_hi16_val(pc, target); } -static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target) +static inline uint32_t reloc_pc16_val(void *pc, intptr_t target) { int32_t disp; - disp = target - (tcg_target_long) pc - 4; + disp = target - (intptr_t)pc - 4; if (disp != (disp << 14) >> 14) { tcg_abort (); } @@ -157,14 +157,14 @@ static inline uint32_t reloc_26_val (void *pc, tcg_target_long target) return (target >> 2) & 0x3ffffff; } -static inline void reloc_pc26 (void *pc, tcg_target_long target) +static inline void reloc_pc26(void *pc, intptr_t target) { *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff) | reloc_26_val(pc, target); } static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { value += addend; switch(type) { diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 453ab6b580..4d6ee1e7a2 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -204,7 +204,7 @@ static void reloc_pc14 (void *pc, tcg_target_long target) } static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { value += addend; switch (type) { diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 939f7cb318..62af42c2bf 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -208,7 +208,7 @@ static void reloc_pc14 (void *pc, tcg_target_long target) } static void patch_reloc (uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { value += addend; switch (type) { diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index f229f1c346..adf709941f 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -351,10 +351,10 @@ static uint8_t *tb_ret_addr; static uint64_t facilities; static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { - tcg_target_long code_ptr_tl = (tcg_target_long)code_ptr; - tcg_target_long pcrel2; + intptr_t code_ptr_tl = (intptr_t)code_ptr; + intptr_t pcrel2; /* ??? Not the usual definition of "addend". */ pcrel2 = (value - (code_ptr_tl + addend)) >> 1; diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 5bfd29c3b4..9f2e2c983f 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -252,7 +252,7 @@ static inline int check_fit_i32(uint32_t val, unsigned int bits) } static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { uint32_t insn; value += addend; @@ -264,7 +264,7 @@ static void patch_reloc(uint8_t *code_ptr, int type, *(uint32_t *)code_ptr = value; break; case R_SPARC_WDISP16: - value -= (long)code_ptr; + value -= (intptr_t)code_ptr; if (!check_fit_tl(value >> 2, 16)) { tcg_abort(); } @@ -274,7 +274,7 @@ static void patch_reloc(uint8_t *code_ptr, int type, *(uint32_t *)code_ptr = insn; break; case R_SPARC_WDISP19: - value -= (long)code_ptr; + value -= (intptr_t)code_ptr; if (!check_fit_tl(value >> 2, 19)) { tcg_abort(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index 251d39050c..75df845b11 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -66,7 +66,7 @@ static void tcg_target_init(TCGContext *s); static void tcg_target_qemu_prologue(TCGContext *s); static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend); + intptr_t value, intptr_t addend); /* The CIE and FDE header definitions will be common to all hosts. */ typedef struct { @@ -143,7 +143,7 @@ static inline void tcg_out64(TCGContext *s, uint64_t v) /* label relocation processing */ static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, - int label_index, long addend) + int label_index, intptr_t addend) { TCGLabel *l; TCGRelocation *r; @@ -169,11 +169,12 @@ static void tcg_out_label(TCGContext *s, int label_index, void *ptr) { TCGLabel *l; TCGRelocation *r; - tcg_target_long value = (tcg_target_long)ptr; + intptr_t value = (intptr_t)ptr; l = &s->labels[label_index]; - if (l->has_value) + if (l->has_value) { tcg_abort(); + } r = l->u.first_reloc; while (r != NULL) { patch_reloc(r->ptr, r->type, value, r->addend); diff --git a/tcg/tcg.h b/tcg/tcg.h index 8fe80692b2..715812a283 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -139,13 +139,13 @@ typedef struct TCGRelocation { struct TCGRelocation *next; int type; uint8_t *ptr; - tcg_target_long addend; + intptr_t addend; } TCGRelocation; typedef struct TCGLabel { int has_value; union { - tcg_target_ulong value; + uintptr_t value; TCGRelocation *first_reloc; } u; } TCGLabel; diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c index e118bc7179..49be6a57f0 100644 --- a/tcg/tci/tcg-target.c +++ b/tcg/tci/tcg-target.c @@ -370,7 +370,7 @@ static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { #endif static void patch_reloc(uint8_t *code_ptr, int type, - tcg_target_long value, tcg_target_long addend) + intptr_t value, intptr_t addend) { /* tcg_out_reloc always uses the same type, addend. */ assert(type == sizeof(tcg_target_long)); From 48bc6bab479e5abb542119f3974603afd882c246 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 15:38:41 -0700 Subject: [PATCH 15/29] tcg: Use uintptr_t in TCGHelperInfo Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/tcg.c | 6 +++--- tcg/tcg.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 75df845b11..714b0c719a 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -634,7 +634,7 @@ void tcg_register_helper(void *func, const char *name) s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo)); s->allocated_helpers = n; } - s->helpers[s->nb_helpers].func = (tcg_target_ulong)func; + s->helpers[s->nb_helpers].func = (uintptr_t)func; s->helpers[s->nb_helpers].name = name; s->nb_helpers++; } @@ -864,11 +864,11 @@ static int helper_cmp(const void *p1, const void *p2) } /* find helper definition (Note: A hash table would be better) */ -static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val) +static TCGHelperInfo *tcg_find_helper(TCGContext *s, uintptr_t val) { int m, m_min, m_max; TCGHelperInfo *th; - tcg_target_ulong v; + uintptr_t v; if (unlikely(!s->helpers_sorted)) { qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), diff --git a/tcg/tcg.h b/tcg/tcg.h index 715812a283..d27df66f8d 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -402,7 +402,7 @@ typedef struct TCGTemp { } TCGTemp; typedef struct TCGHelperInfo { - tcg_target_ulong func; + uintptr_t func; const char *name; } TCGHelperInfo; From 8cfd04959a023f87e1e6727e608a20f168441370 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 15:53:10 -0700 Subject: [PATCH 16/29] tcg: Change tcg_gen_exit_tb argument to uintptr_t And update all users. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- include/exec/gen-icount.h | 4 ++-- target-alpha/translate.c | 8 ++++---- target-arm/translate.c | 2 +- target-cris/translate.c | 2 +- target-i386/translate.c | 2 +- target-lm32/translate.c | 2 +- target-m68k/translate.c | 2 +- target-microblaze/translate.c | 2 +- target-mips/translate.c | 2 +- target-moxie/translate.c | 2 +- target-openrisc/translate.c | 2 +- target-ppc/translate.c | 2 +- target-s390x/translate.c | 8 ++++---- target-sh4/translate.c | 2 +- target-sparc/translate.c | 2 +- target-unicore32/translate.c | 2 +- target-xtensa/translate.c | 2 +- tcg/tcg-op.h | 2 +- 18 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h index 4fc7b2981d..39a6b61e4f 100644 --- a/include/exec/gen-icount.h +++ b/include/exec/gen-icount.h @@ -39,12 +39,12 @@ static inline void gen_tb_start(void) static void gen_tb_end(TranslationBlock *tb, int num_insns) { gen_set_label(exitreq_label); - tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_REQUESTED); + tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED); if (use_icount) { *icount_arg = num_insns; gen_set_label(icount_label); - tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_ICOUNT_EXPIRED); + tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED); } } diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 309dea6ff0..28ce4363f1 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -415,7 +415,7 @@ static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp) } else if (use_goto_tb(ctx, dest)) { tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_exit_tb((tcg_target_long)ctx->tb); + tcg_gen_exit_tb((uintptr_t)ctx->tb); return EXIT_GOTO_TB; } else { tcg_gen_movi_i64(cpu_pc, dest); @@ -434,12 +434,12 @@ static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond, tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, ctx->pc); - tcg_gen_exit_tb((tcg_target_long)ctx->tb); + tcg_gen_exit_tb((uintptr_t)ctx->tb); gen_set_label(lab_true); tcg_gen_goto_tb(1); tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_exit_tb((tcg_target_long)ctx->tb + 1); + tcg_gen_exit_tb((uintptr_t)ctx->tb + 1); return EXIT_GOTO_TB; } else { @@ -1629,7 +1629,7 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int palcode) we change the PAL base register. */ if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) { tcg_gen_goto_tb(0); - tcg_gen_exit_tb((tcg_target_long)ctx->tb); + tcg_gen_exit_tb((uintptr_t)ctx->tb); return EXIT_GOTO_TB; } diff --git a/target-arm/translate.c b/target-arm/translate.c index d1e8538142..9160ced4fe 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -3356,7 +3356,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); gen_set_pc_im(dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { gen_set_pc_im(dest); tcg_gen_exit_tb(0); diff --git a/target-cris/translate.c b/target-cris/translate.c index 2a4beeb869..617e1b4242 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -558,7 +558,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(env_pc, dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_tl(env_pc, dest); tcg_gen_exit_tb(0); diff --git a/target-i386/translate.c b/target-i386/translate.c index 065a9d320e..6d879003b3 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2413,7 +2413,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); gen_jmp_im(eip); - tcg_gen_exit_tb((tcg_target_long)tb + tb_num); + tcg_gen_exit_tb((uintptr_t)tb + tb_num); } else { /* jump to another page: currently not optimized */ gen_jmp_im(eip); diff --git a/target-lm32/translate.c b/target-lm32/translate.c index 1247287050..6ea0ecd63b 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -129,7 +129,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) likely(!dc->singlestep_enabled)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_pc, dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_tl(cpu_pc, dest); if (dc->singlestep_enabled) { diff --git a/target-m68k/translate.c b/target-m68k/translate.c index d562eebef3..0be0a96732 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -869,7 +869,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest) (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(QREG_PC, dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { gen_jmp_im(s, dest); tcg_gen_exit_tb(0); diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index cd4357703f..0673176957 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -138,7 +138,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_SR[SR_PC], dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_tl(cpu_SR[SR_PC], dest); tcg_gen_exit_tb(0); diff --git a/target-mips/translate.c b/target-mips/translate.c index e2eb908cf3..ad43d59103 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -3581,7 +3581,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) likely(!ctx->singlestep_enabled)) { tcg_gen_goto_tb(n); gen_save_pc(dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { gen_save_pc(dest); if (ctx->singlestep_enabled) { diff --git a/target-moxie/translate.c b/target-moxie/translate.c index 8cc0bb7bfb..a93196f47b 100644 --- a/target-moxie/translate.c +++ b/target-moxie/translate.c @@ -135,7 +135,7 @@ static inline void gen_goto_tb(CPUMoxieState *env, DisasContext *ctx, !ctx->singlestep_enabled) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_i32(cpu_pc, dest); if (ctx->singlestep_enabled) { diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index a6050ba6d8..723b77d3b4 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -198,7 +198,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) likely(!dc->singlestep_enabled)) { tcg_gen_movi_tl(cpu_pc, dest); tcg_gen_goto_tb(n); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_tl(cpu_pc, dest); if (dc->singlestep_enabled) { diff --git a/target-ppc/translate.c b/target-ppc/translate.c index f07d70d866..2ffb2708d2 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -3551,7 +3551,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) likely(!ctx->singlestep_enabled)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_nip, dest & ~3); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_tl(cpu_nip, dest & ~3); if (unlikely(ctx->singlestep_enabled)) { diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 1fb76c5264..afe90eb8be 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -1169,7 +1169,7 @@ static ExitStatus help_goto_direct(DisasContext *s, uint64_t dest) update_cc_op(s); tcg_gen_goto_tb(0); tcg_gen_movi_i64(psw_addr, dest); - tcg_gen_exit_tb((tcg_target_long)s->tb); + tcg_gen_exit_tb((uintptr_t)s->tb); return EXIT_GOTO_TB; } else { tcg_gen_movi_i64(psw_addr, dest); @@ -1227,13 +1227,13 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c, /* Branch not taken. */ tcg_gen_goto_tb(0); tcg_gen_movi_i64(psw_addr, s->next_pc); - tcg_gen_exit_tb((tcg_target_long)s->tb + 0); + tcg_gen_exit_tb((uintptr_t)s->tb + 0); /* Branch taken. */ gen_set_label(lab); tcg_gen_goto_tb(1); tcg_gen_movi_i64(psw_addr, dest); - tcg_gen_exit_tb((tcg_target_long)s->tb + 1); + tcg_gen_exit_tb((uintptr_t)s->tb + 1); ret = EXIT_GOTO_TB; } else { @@ -1256,7 +1256,7 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c, update_cc_op(s); tcg_gen_goto_tb(0); tcg_gen_movi_i64(psw_addr, s->next_pc); - tcg_gen_exit_tb((tcg_target_long)s->tb + 0); + tcg_gen_exit_tb((uintptr_t)s->tb + 0); gen_set_label(lab); if (is_imm) { diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 59f3d47023..c06b29f1dc 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -186,7 +186,7 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) /* Use a direct jump if in same page and singlestep not enabled */ tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_i32(cpu_pc, dest); if (ctx->singlestep_enabled) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 093e0e2c78..36615f1979 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -322,7 +322,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, tcg_gen_goto_tb(tb_num); tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); - tcg_gen_exit_tb((tcg_target_long)tb + tb_num); + tcg_gen_exit_tb((uintptr_t)tb + tb_num); } else { /* jump to another page: currently not optimized */ tcg_gen_movi_tl(cpu_pc, pc); diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index 68be1c64e0..1246895f86 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -1100,7 +1100,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); gen_set_pc_im(dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { gen_set_pc_im(dest); tcg_gen_exit_tb(0); diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 504cc539e3..24343bdf60 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -400,7 +400,7 @@ static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) } else { if (slot >= 0) { tcg_gen_goto_tb(slot); - tcg_gen_exit_tb((tcg_target_long)dc->tb + slot); + tcg_gen_exit_tb((uintptr_t)dc->tb + slot); } else { tcg_gen_exit_tb(0); } diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 3de7545a46..bb30a7cf39 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -2631,7 +2631,7 @@ static inline void tcg_gen_debug_insn_start(uint64_t pc) #endif } -static inline void tcg_gen_exit_tb(tcg_target_long val) +static inline void tcg_gen_exit_tb(uintptr_t val) { tcg_gen_op1i(INDEX_op_exit_tb, val); } From a05b5b9be0fec96c89e00abaa964be7ce9e661ac Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 17:07:26 -0700 Subject: [PATCH 17/29] tcg: Change tcg_out_ld/st offset to intptr_t Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 4 ++-- tcg/arm/tcg-target.c | 4 ++-- tcg/hppa/tcg-target.c | 4 ++-- tcg/i386/tcg-target.c | 4 ++-- tcg/ia64/tcg-target.c | 4 ++-- tcg/mips/tcg-target.c | 4 ++-- tcg/ppc/tcg-target.c | 8 ++++---- tcg/ppc64/tcg-target.c | 8 ++++---- tcg/s390/tcg-target.c | 4 ++-- tcg/sparc/tcg-target.c | 4 ++-- tcg/tcg.c | 4 ++-- tcg/tci/tcg-target.c | 4 ++-- 12 files changed, 28 insertions(+), 28 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 7dde210303..c472a4aeb4 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -423,14 +423,14 @@ static inline void tcg_out_mov(TCGContext *s, } static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, (type == TCG_TYPE_I64) ? LDST_64 : LDST_32, LDST_LD, arg, arg1, arg2); } static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, (type == TCG_TYPE_I64) ? LDST_64 : LDST_32, LDST_ST, arg, arg1, arg2); diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index e93c67f74d..5d2db3648b 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -2065,13 +2065,13 @@ static void tcg_target_init(TCGContext *s) } static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ld32u(s, COND_AL, arg, arg1, arg2); } static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_st32(s, COND_AL, arg, arg1, arg2); } diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index f770250844..0150e62c8d 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -392,14 +392,14 @@ static void tcg_out_ldst(TCGContext *s, int ret, int addr, /* This function is required by tcg.c. */ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, ret, arg1, arg2, INSN_LDW); } /* This function is required by tcg.c. */ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg ret, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, ret, arg1, arg2, INSN_STW); } diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 031df7163d..70e80f91cb 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -595,14 +595,14 @@ static inline void tcg_out_pop(TCGContext *s, int reg) } static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0); tcg_out_modrm_offset(s, opc, ret, arg1, arg2); } static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0); tcg_out_modrm_offset(s, opc, arg, arg1, arg2); diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index c499ee8bf9..0a3ff70025 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -993,7 +993,7 @@ static inline void tcg_out_st_rel(TCGContext *s, uint64_t opc_m4, TCGArg arg, } static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { if (type == TCG_TYPE_I32) { tcg_out_ld_rel(s, OPC_LD4_M1, arg, arg1, arg2); @@ -1003,7 +1003,7 @@ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, } static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { if (type == TCG_TYPE_I32) { tcg_out_st_rel(s, OPC_ST4_M4, arg, arg1, arg2); diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index f7ea140177..6bf7dba82d 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -514,13 +514,13 @@ static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg, } static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, OPC_LW, arg, arg1, arg2); } static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, OPC_SW, arg, arg1, arg2); } diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 4d6ee1e7a2..f45ce7ce84 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -1062,14 +1062,14 @@ static void tcg_target_qemu_prologue (TCGContext *s) #endif } -static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, - tcg_target_long arg2) +static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, + intptr_t arg2) { tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX); } -static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, - tcg_target_long arg2) +static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, + intptr_t arg2) { tcg_out_ldst (s, arg, arg1, arg2, STW, STWX); } diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 62af42c2bf..c5cfe828f1 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -1072,8 +1072,8 @@ static void tcg_target_qemu_prologue (TCGContext *s) tcg_out32(s, BCLR | BO_ALWAYS); } -static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, - tcg_target_long arg2) +static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, + intptr_t arg2) { if (type == TCG_TYPE_I32) tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX); @@ -1081,8 +1081,8 @@ static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX); } -static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, - tcg_target_long arg2) +static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, + intptr_t arg2) { if (type == TCG_TYPE_I32) tcg_out_ldst (s, arg, arg1, arg2, STW, STWX); diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index adf709941f..a1dcb3d826 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -771,7 +771,7 @@ static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy, /* load data without address translation or endianness conversion */ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data, - TCGReg base, tcg_target_long ofs) + TCGReg base, intptr_t ofs) { if (type == TCG_TYPE_I32) { tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs); @@ -781,7 +781,7 @@ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data, } static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data, - TCGReg base, tcg_target_long ofs) + TCGReg base, intptr_t ofs) { if (type == TCG_TYPE_I32) { tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs); diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 9f2e2c983f..5eb8c7633f 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -436,13 +436,13 @@ static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, } static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, ret, arg1, arg2, (type == TCG_TYPE_I32 ? LDUW : LDX)); } static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, tcg_target_long arg2) + TCGReg arg1, intptr_t arg2) { tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX)); } diff --git a/tcg/tcg.c b/tcg/tcg.c index 714b0c719a..7ba92086d2 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -93,14 +93,14 @@ static void tcg_register_jit_int(void *buf, size_t size, /* Forward declarations for functions declared and used in tcg-target.c. */ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str); static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, - tcg_target_long arg2); + intptr_t arg2); static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, tcg_target_long arg); static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, const int *const_args); static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, - tcg_target_long arg2); + intptr_t arg2); static int tcg_target_const_match(tcg_target_long val, const TCGArgConstraint *arg_ct); diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c index 49be6a57f0..281d7d50f3 100644 --- a/tcg/tci/tcg-target.c +++ b/tcg/tci/tcg-target.c @@ -488,7 +488,7 @@ static void tci_out_label(TCGContext *s, TCGArg arg) } static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, - tcg_target_long arg2) + intptr_t arg2) { uint8_t *old_code_ptr = s->code_ptr; if (type == TCG_TYPE_I32) { @@ -842,7 +842,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, } static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, - tcg_target_long arg2) + intptr_t arg2) { uint8_t *old_code_ptr = s->code_ptr; if (type == TCG_TYPE_I32) { From d3452f1f40956e50142d32afbc021c53026a1770 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 17:12:38 -0700 Subject: [PATCH 18/29] tcg: Use appropriate types in tcg_reg_alloc_call Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/tcg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 7ba92086d2..99f3b2ca8f 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -2070,7 +2070,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params; TCGArg arg, func_arg; TCGTemp *ts; - tcg_target_long stack_offset, call_stack_size, func_addr; + intptr_t stack_offset; + size_t call_stack_size; + uintptr_t func_addr; int const_func_arg, allocate_args; TCGRegSet allocated_regs; const TCGArgConstraint *arg_ct; From edee2579ae3722d28756ce04ec665ea9522d8600 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 17:20:30 -0700 Subject: [PATCH 19/29] tcg: Fix jit debug for x32 Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/tcg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 99f3b2ca8f..fd7fb6b85e 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -49,10 +49,10 @@ #include "tcg-op.h" -#if TCG_TARGET_REG_BITS == 64 -# define ELF_CLASS ELFCLASS64 -#else +#if UINTPTR_MAX == UINT32_MAX # define ELF_CLASS ELFCLASS32 +#else +# define ELF_CLASS ELFCLASS64 #endif #ifdef HOST_WORDS_BIGENDIAN # define ELF_DATA ELFDATA2MSB @@ -82,8 +82,8 @@ typedef struct { typedef struct QEMU_PACKED { uint32_t len __attribute__((aligned((sizeof(void *))))); uint32_t cie_offset; - tcg_target_long func_start; - tcg_target_long func_len; + uintptr_t func_start; + uintptr_t func_len; } DebugFrameFDEHeader; static void tcg_register_jit_int(void *buf, size_t size, From 357e3d8a297003f9d79f08e45a79a73eb2d12f5b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 15:37:16 -0700 Subject: [PATCH 20/29] tcg-i386: Use intptr_t appropriately Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 70e80f91cb..247c9d228a 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -430,8 +430,7 @@ static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm) that will follow the instruction. */ static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm, - int index, int shift, - tcg_target_long offset) + int index, int shift, intptr_t offset) { int mod, len; @@ -439,8 +438,8 @@ static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm, if (TCG_TARGET_REG_BITS == 64) { /* Try for a rip-relative addressing mode. This has replaced the 32-bit-mode absolute addressing encoding. */ - tcg_target_long pc = (tcg_target_long)s->code_ptr + 5 + ~rm; - tcg_target_long disp = offset - pc; + intptr_t pc = (intptr_t)s->code_ptr + 5 + ~rm; + intptr_t disp = offset - pc; if (disp == (int32_t)disp) { tcg_out_opc(s, opc, r, 0, 0); tcg_out8(s, (LOWREGMASK(r) << 3) | 5); @@ -514,7 +513,7 @@ static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm, /* A simplification of the above with no index or shift. */ static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, - int rm, tcg_target_long offset) + int rm, intptr_t offset) { tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset); } @@ -559,7 +558,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, } /* Try a 7 byte pc-relative lea before the 10 byte movq. */ - diff = arg - ((tcg_target_long)s->code_ptr + 7); + diff = arg - ((uintptr_t)s->code_ptr + 7); if (diff == (int32_t)diff) { tcg_out_opc(s, OPC_LEA | P_REXW, ret, 0, 0); tcg_out8(s, (LOWREGMASK(ret) << 3) | 5); @@ -757,7 +756,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small) TCGLabel *l = &s->labels[label_index]; if (l->has_value) { - val = l->u.value - (tcg_target_long)s->code_ptr; + val = l->u.value - (intptr_t)s->code_ptr; val1 = val - 2; if ((int8_t)val1 == val1) { if (opc == -1) { @@ -997,9 +996,9 @@ static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGArg dest, } #endif -static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest) +static void tcg_out_branch(TCGContext *s, int call, uintptr_t dest) { - tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5; + intptr_t disp = dest - (intptr_t)s->code_ptr - 5; if (disp == (int32_t)disp) { tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0); @@ -1011,12 +1010,12 @@ static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest) } } -static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest) +static inline void tcg_out_calli(TCGContext *s, uintptr_t dest) { tcg_out_branch(s, 1, dest); } -static void tcg_out_jmp(TCGContext *s, tcg_target_long dest) +static void tcg_out_jmp(TCGContext *s, uintptr_t dest) { tcg_out_branch(s, 0, dest); } @@ -1154,8 +1153,7 @@ static inline void setup_guest_base_seg(void) { } #endif /* SOFTMMU */ static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi, - int base, tcg_target_long ofs, int seg, - int sizeop) + int base, intptr_t ofs, int seg, int sizeop) { #ifdef TARGET_WORDS_BIGENDIAN const int bswap = 1; @@ -1305,7 +1303,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, } static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi, - int base, tcg_target_long ofs, int seg, + int base, intptr_t ofs, int seg, int sizeop) { #ifdef TARGET_WORDS_BIGENDIAN @@ -1519,7 +1517,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) do_getpc(l->raddr)); } - tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]); + tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[s_bits]); data_reg = l->datalo_reg; switch(opc) { @@ -1560,7 +1558,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) } /* Jump to the code corresponding to next IR of qemu_st */ - tcg_out_jmp(s, (tcg_target_long)l->raddr); + tcg_out_jmp(s, (uintptr_t)l->raddr); } /* @@ -1625,9 +1623,8 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) } } - tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]); - - tcg_out_jmp(s, (tcg_target_long)l->raddr); + tcg_out_calli(s, (uintptr_t)qemu_st_helpers[s_bits]); + tcg_out_jmp(s, (uintptr_t)l->raddr); } /* @@ -1668,7 +1665,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, switch(opc) { case INDEX_op_exit_tb: tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]); - tcg_out_jmp(s, (tcg_target_long) tb_ret_addr); + tcg_out_jmp(s, (uintptr_t)tb_ret_addr); break; case INDEX_op_goto_tb: if (s->tb_jmp_offset) { @@ -1679,7 +1676,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } else { /* indirect jump method */ tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1, - (tcg_target_long)(s->tb_next + args[0])); + (intptr_t)(s->tb_next + args[0])); } s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf; break; @@ -2372,7 +2369,7 @@ static DebugFrame debug_frame = { #if defined(ELF_HOST_MACHINE) void tcg_register_jit(void *buf, size_t buf_size) { - debug_frame.fde.func_start = (tcg_target_long) buf; + debug_frame.fde.func_start = (uintptr_t)buf; debug_frame.fde.func_len = buf_size; tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); From d5dad3be314dfec80ebb1c69266ae62edfea1850 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 16:50:38 -0700 Subject: [PATCH 21/29] tcg-i386: Adjust tcg_out_tlb_load for x32 Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 247c9d228a..cde134f60f 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1085,33 +1085,46 @@ static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx, const int addrlo = args[addrlo_idx]; const int r0 = TCG_REG_L0; const int r1 = TCG_REG_L1; - TCGType type = TCG_TYPE_I32; - int rexw = 0; + TCGType ttype = TCG_TYPE_I32; + TCGType htype = TCG_TYPE_I32; + int trexw = 0, hrexw = 0; - if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) { - type = TCG_TYPE_I64; - rexw = P_REXW; + if (TCG_TARGET_REG_BITS == 64) { + if (TARGET_LONG_BITS == 64) { + ttype = TCG_TYPE_I64; + trexw = P_REXW; + } + if (TCG_TYPE_PTR == TCG_TYPE_I64) { + htype = TCG_TYPE_I64; + hrexw = P_REXW; + } } - tcg_out_mov(s, type, r0, addrlo); - tcg_out_mov(s, type, r1, addrlo); + tcg_out_mov(s, htype, r0, addrlo); + tcg_out_mov(s, ttype, r1, addrlo); - tcg_out_shifti(s, SHIFT_SHR + rexw, r0, + tcg_out_shifti(s, SHIFT_SHR + hrexw, r0, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); - tgen_arithi(s, ARITH_AND + rexw, r1, + tgen_arithi(s, ARITH_AND + trexw, r1, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0); - tgen_arithi(s, ARITH_AND + rexw, r0, + tgen_arithi(s, ARITH_AND + hrexw, r0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0); - tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r0, TCG_AREG0, r0, 0, + tcg_out_modrm_sib_offset(s, OPC_LEA + hrexw, r0, TCG_AREG0, r0, 0, offsetof(CPUArchState, tlb_table[mem_index][0]) + which); /* cmp 0(r0), r1 */ - tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r1, r0, 0); + tcg_out_modrm_offset(s, OPC_CMP_GvEv + trexw, r1, r0, 0); - tcg_out_mov(s, type, r1, addrlo); + /* Prepare for both the fast path add of the tlb addend, and the slow + path function argument setup. There are two cases worth note: + For 32-bit guest and x86_64 host, MOVL zero-extends the guest address + before the fastpath ADDQ below. For 64-bit guest and x32 host, MOVQ + copies the entire guest address for the slow path, while truncation + for the 32-bit host happens with the fastpath ADDL below. */ + tcg_out_mov(s, ttype, r1, addrlo); /* jne slow_path */ tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0); @@ -1131,7 +1144,7 @@ static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx, /* TLB Hit. */ /* add addend(r0), r1 */ - tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r1, r0, + tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r1, r0, offsetof(CPUTLBEntry, addend) - which); } #elif defined(__x86_64__) && defined(__linux__) From c72b26ec92eb93a92852ab1d23acb5a945de5062 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Aug 2013 12:20:05 -0700 Subject: [PATCH 22/29] configure: Allow x32 as a host Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- configure | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 0a55c20252..af6b048c6e 100755 --- a/configure +++ b/configure @@ -362,7 +362,11 @@ if test ! -z "$cpu" ; then elif check_define __i386__ ; then cpu="i386" elif check_define __x86_64__ ; then - cpu="x86_64" + if check_define __ILP32__ ; then + cpu="x32" + else + cpu="x86_64" + fi elif check_define __sparc__ ; then if check_define __arch64__ ; then cpu="sparc64" @@ -399,7 +403,7 @@ ARCH= # Normalise host CPU name and set ARCH. # Note that this case should only have supported host CPUs, not guests. case "$cpu" in - ia64|ppc|ppc64|s390|s390x|sparc64) + ia64|ppc|ppc64|s390|s390x|sparc64|x32) cpu="$cpu" ;; i386|i486|i586|i686|i86pc|BePC) @@ -550,7 +554,7 @@ Haiku) kvm="yes" vhost_net="yes" vhost_scsi="yes" - if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then + if [ "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "x32" ] ; then audio_possible_drivers="$audio_possible_drivers fmod" fi QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES" @@ -977,6 +981,11 @@ case "$cpu" in LDFLAGS="-m64 $LDFLAGS" cc_i386='$(CC) -m32' ;; + x32) + CPU_CFLAGS="-mx32" + LDFLAGS="-mx32 $LDFLAGS" + cc_i386='$(CC) -m32' + ;; # No special flags required for other host CPUs esac @@ -1251,7 +1260,7 @@ fi if test "$pie" = ""; then case "$cpu-$targetos" in - i386-Linux|x86_64-Linux|i386-OpenBSD|x86_64-OpenBSD) + i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD) ;; *) pie="no" @@ -3506,7 +3515,7 @@ fi if test "$pie" = "no" ; then textseg_addr= case "$cpu" in - arm | hppa | i386 | m68k | ppc | ppc64 | s390* | sparc | sparc64 | x86_64) + arm | hppa | i386 | m68k | ppc | ppc64 | s390* | sparc | sparc64 | x86_64 | x32) textseg_addr=0x60000000 ;; mips) @@ -3681,7 +3690,7 @@ echo "libs_softmmu=$libs_softmmu" >> $config_host_mak echo "ARCH=$ARCH" >> $config_host_mak case "$cpu" in - arm|i386|x86_64|ppc|aarch64) + arm|i386|x86_64|x32|ppc|aarch64) # The TCG interpreter currently does not support ld/st optimization. if test "$tcg_interpreter" = "no" ; then echo "CONFIG_QEMU_LDST_OPTIMIZATION=y" >> $config_host_mak @@ -4116,7 +4125,7 @@ elif test "$ARCH" = "sparc64" ; then QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/sparc $QEMU_INCLUDES" elif test "$ARCH" = "s390x" ; then QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/s390 $QEMU_INCLUDES" -elif test "$ARCH" = "x86_64" ; then +elif test "$ARCH" = "x86_64" -o "$ARCH" = "x32" ; then QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/i386 $QEMU_INCLUDES" else QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/\$(ARCH) $QEMU_INCLUDES" @@ -4178,7 +4187,7 @@ fi if test "$linux" = "yes" ; then mkdir -p linux-headers case "$cpu" in - i386|x86_64) + i386|x86_64|x32) linux_arch=x86 ;; ppcemb|ppc|ppc64) @@ -4444,7 +4453,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_HPPA_DIS=y" >> $config_target_mak echo "CONFIG_HPPA_DIS=y" >> config-all-disas.mak ;; - i386|x86_64) + i386|x86_64|x32) echo "CONFIG_I386_DIS=y" >> $config_target_mak echo "CONFIG_I386_DIS=y" >> config-all-disas.mak ;; From 0f842f8a246f2b5b51a11c13f933bf7a90ae8e96 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Aug 2013 10:22:54 -0700 Subject: [PATCH 23/29] exec: Reorganize the GETRA/GETPC macros Always define GETRA; use __builtin_extract_return_addr, rather than having a special case for s390. Split GETPC_ADJ out of GETPC; use 2 universally, rather than having a special case for arm. Rename GETPC_LDST to GETRA_LDST to indicate that it does not contain the GETPC_ADJ value. Likewise with GETPC_EXT to GETRA_EXT. Perform the GETPC_ADJ adjustment inside helper_ret_ld/st. This will allow backends to pass along the "true" return address rather than the massaged GETPC value. In the meantime, double application of GETPC_ADJ does not hurt, since the call insn in all ISAs is at least 4 bytes long. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- include/exec/exec-all.h | 84 +++++++++++++++------------------ include/exec/softmmu_template.h | 24 +++++++--- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index ffb69a4c70..6f71a4fdae 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -295,47 +295,42 @@ static inline void tb_add_jump(TranslationBlock *tb, int n, } } -/* The return address may point to the start of the next instruction. - Subtracting one gets us the call instruction itself. */ +/* GETRA is the true target of the return instruction that we'll execute, + defined here for simplicity of defining the follow-up macros. */ #if defined(CONFIG_TCG_INTERPRETER) extern uintptr_t tci_tb_ptr; -# define GETPC() tci_tb_ptr -#elif defined(__s390__) && !defined(__s390x__) -# define GETPC() \ - (((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1) -#elif defined(__arm__) -/* Thumb return addresses have the low bit set, so we need to subtract two. - This is still safe in ARM mode because instructions are 4 bytes. */ -# define GETPC() ((uintptr_t)__builtin_return_address(0) - 2) +# define GETRA() tci_tb_ptr #else -# define GETPC() ((uintptr_t)__builtin_return_address(0) - 1) +# define GETRA() \ + ((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0))) #endif -#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) -/* qemu_ld/st optimization split code generation to fast and slow path, thus, - it needs special handling for an MMU helper which is called from the slow - path, to get the fast path's pc without any additional argument. - It uses a tricky solution which embeds the fast path pc into the slow path. +/* The true return address will often point to a host insn that is part of + the next translated guest insn. Adjust the address backward to point to + the middle of the call insn. Subtracting one would do the job except for + several compressed mode architectures (arm, mips) which set the low bit + to indicate the compressed mode; subtracting two works around that. It + is also the case that there are no host isas that contain a call insn + smaller than 4 bytes, so we don't worry about special-casing this. */ +#if defined(CONFIG_TCG_INTERPRETER) +# define GETPC_ADJ 0 +#else +# define GETPC_ADJ 2 +#endif - Code flow in slow path: - (1) pre-process - (2) call MMU helper - (3) jump to (5) - (4) fast path information (implementation specific) - (5) post-process (e.g. stack adjust) - (6) jump to corresponding code of the next of fast path - */ -# if defined(__i386__) || defined(__x86_64__) -# define GETPC_EXT() GETPC() -# elif defined (_ARCH_PPC) && !defined (_ARCH_PPC64) -# define GETRA() ((uintptr_t)__builtin_return_address(0)) -# define GETPC_LDST() ((uintptr_t) ((*(int32_t *)(GETRA() - 4)) - 1)) +#define GETPC() (GETRA() - GETPC_ADJ) + +/* The LDST optimizations splits code generation into fast and slow path. + In some implementations, we pass the "logical" return address manually; + in others, we must infer the logical return from the true return. */ +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) +# if defined (_ARCH_PPC) && !defined (_ARCH_PPC64) +# define GETRA_LDST(RA) (*(int32_t *)((RA) - 4)) # elif defined(__arm__) /* We define two insns between the return address and the branch back to straight-line. Find and decode that branch insn. */ -# define GETRA() ((uintptr_t)__builtin_return_address(0)) -# define GETPC_LDST() tcg_getpc_ldst(GETRA()) -static inline uintptr_t tcg_getpc_ldst(uintptr_t ra) +# define GETRA_LDST(RA) tcg_getra_ldst(RA) +static inline uintptr_t tcg_getra_ldst(uintptr_t ra) { int32_t b; ra += 8; /* skip the two insns */ @@ -343,33 +338,32 @@ static inline uintptr_t tcg_getpc_ldst(uintptr_t ra) b = (b << 8) >> (8 - 2); /* extract the displacement */ ra += 8; /* branches are relative to pc+8 */ ra += b; /* apply the displacement */ - ra -= 4; /* return a pointer into the current opcode, - not the start of the next opcode */ return ra; } # elif defined(__aarch64__) -# define GETRA() ((uintptr_t)__builtin_return_address(0)) -# define GETPC_LDST() tcg_getpc_ldst(GETRA()) -static inline uintptr_t tcg_getpc_ldst(uintptr_t ra) +# define GETRA_LDST(RA) tcg_getra_ldst(RA) +static inline uintptr_t tcg_getra_ldst(uintptr_t ra) { int32_t b; ra += 4; /* skip one instruction */ b = *(int32_t *)ra; /* load the branch insn */ b = (b << 6) >> (6 - 2); /* extract the displacement */ ra += b; /* apply the displacement */ - ra -= 4; /* return a pointer into the current opcode, - not the start of the next opcode */ return ra; } -# else -# error "CONFIG_QEMU_LDST_OPTIMIZATION needs GETPC_LDST() implementation!" # endif +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */ + +/* ??? Delete these once they are no longer used. */ bool is_tcg_gen_code(uintptr_t pc_ptr); -# ifndef GETPC_EXT -# define GETPC_EXT() (is_tcg_gen_code(GETRA()) ? GETPC_LDST() : GETPC()) -# endif +#ifdef GETRA_LDST +# define GETRA_EXT() tcg_getra_ext(GETRA()) +static inline uintptr_t tcg_getra_ext(uintptr_t ra) +{ + return is_tcg_gen_code(ra) ? GETRA_LDST(ra) : ra; +} #else -# define GETPC_EXT() GETPC() +# define GETRA_EXT() GETRA() #endif #if !defined(CONFIG_USER_ONLY) diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h index eaca9e1035..2fc6ea3235 100644 --- a/include/exec/softmmu_template.h +++ b/include/exec/softmmu_template.h @@ -86,6 +86,9 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; uintptr_t haddr; + /* Adjust the given return address. */ + retaddr -= GETPC_ADJ; + /* If the TLB entry is for a different page, reload and try again. */ if ((addr & TARGET_PAGE_MASK) != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { @@ -121,10 +124,12 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, #endif addr1 = addr & ~(DATA_SIZE - 1); addr2 = addr1 + DATA_SIZE; - res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr1, - mmu_idx, retaddr); - res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr2, - mmu_idx, retaddr); + /* Note the adjustment at the beginning of the function. + Undo that for the recursion. */ + res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX) + (env, addr1, mmu_idx, retaddr + GETPC_ADJ); + res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX) + (env, addr2, mmu_idx, retaddr + GETPC_ADJ); shift = (addr & (DATA_SIZE - 1)) * 8; #ifdef TARGET_WORDS_BIGENDIAN res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); @@ -150,7 +155,7 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, int mmu_idx) { return glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx, - GETPC_EXT()); + GETRA_EXT()); } #ifndef SOFTMMU_CODE_ACCESS @@ -182,6 +187,9 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; uintptr_t haddr; + /* Adjust the given return address. */ + retaddr -= GETPC_ADJ; + /* If the TLB entry is for a different page, reload and try again. */ if ((addr & TARGET_PAGE_MASK) != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { @@ -223,8 +231,10 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, #else uint8_t val8 = val >> (i * 8); #endif + /* Note the adjustment at the beginning of the function. + Undo that for the recursion. */ glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8, - mmu_idx, retaddr); + mmu_idx, retaddr + GETPC_ADJ); } return; } @@ -245,7 +255,7 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, DATA_TYPE val, int mmu_idx) { glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx, - GETPC_EXT()); + GETRA_EXT()); } #endif /* !defined(SOFTMMU_CODE_ACCESS) */ From 5bcebc253c1637d3a5b957abc7460c49a670c4de Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Aug 2013 10:47:49 -0700 Subject: [PATCH 24/29] tcg-i386: Don't perform GETPC adjustment in TCG code Since we now perform it inside the helper, no need to do it here. This also lets us perform a tail-call from the store slow path to the helper. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index cde134f60f..28ed55a096 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1481,12 +1481,6 @@ static void add_qemu_ldst_label(TCGContext *s, } } -/* See the GETPC definition in include/exec/exec-all.h. */ -static inline uintptr_t do_getpc(uint8_t *raddr) -{ - return (uintptr_t)raddr - 1; -} - /* * Generate code for the slow path for a load at the end of block */ @@ -1520,14 +1514,14 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index); ofs += 4; - tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr)); + tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, (uintptr_t)l->raddr); } else { tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0); /* The second argument is already loaded with addrlo. */ tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], l->mem_index); tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[3], - do_getpc(l->raddr)); + (uintptr_t)l->raddr); } tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[s_bits]); @@ -1582,6 +1576,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) int opc = l->opc; int s_bits = opc & 3; uint8_t **label_ptr = &l->label_ptr[0]; + TCGReg retaddr; /* resolve label address */ *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4); @@ -1614,10 +1609,10 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index); ofs += 4; - tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr)); + retaddr = TCG_REG_EAX; + tcg_out_movi(s, TCG_TYPE_I32, retaddr, (uintptr_t)l->raddr); + tcg_out_st(s, TCG_TYPE_I32, retaddr, TCG_REG_ESP, ofs); } else { - uintptr_t pc; - tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0); /* The second argument is already loaded with addrlo. */ tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32), @@ -1625,19 +1620,19 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], l->mem_index); - pc = do_getpc(l->raddr); if (ARRAY_SIZE(tcg_target_call_iarg_regs) > 4) { - tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[4], pc); - } else if (pc == (int32_t)pc) { - tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, 0, pc); + retaddr = tcg_target_call_iarg_regs[4]; + tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr); } else { - tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, pc); - tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RAX, TCG_REG_ESP, 0); + retaddr = TCG_REG_RAX; + tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr); + tcg_out_st(s, TCG_TYPE_PTR, retaddr, TCG_REG_ESP, 0); } } - tcg_out_calli(s, (uintptr_t)qemu_st_helpers[s_bits]); - tcg_out_jmp(s, (uintptr_t)l->raddr); + /* "Tail call" to the helper, with the return address back inline. */ + tcg_out_push(s, retaddr); + tcg_out_jmp(s, (uintptr_t)qemu_st_helpers[s_bits]); } /* From 701e3a5cc02fd52ba59894781e78d433ec043772 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Aug 2013 11:31:48 -0700 Subject: [PATCH 25/29] exec: Rename USUFFIX to LSUFFIX In a following patch, there will be confusion between multiple "unsigned" suffixes; rename this one so as to imply "load". Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- include/exec/softmmu_template.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h index 2fc6ea3235..f9922e2689 100644 --- a/include/exec/softmmu_template.h +++ b/include/exec/softmmu_template.h @@ -28,19 +28,19 @@ #if DATA_SIZE == 8 #define SUFFIX q -#define USUFFIX q +#define LSUFFIX q #define DATA_TYPE uint64_t #elif DATA_SIZE == 4 #define SUFFIX l -#define USUFFIX l +#define LSUFFIX l #define DATA_TYPE uint32_t #elif DATA_SIZE == 2 #define SUFFIX w -#define USUFFIX uw +#define LSUFFIX uw #define DATA_TYPE uint16_t #elif DATA_SIZE == 1 #define SUFFIX b -#define USUFFIX ub +#define LSUFFIX ub #define DATA_TYPE uint8_t #else #error unsupported data size @@ -147,7 +147,7 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, #endif haddr = addr + env->tlb_table[mmu_idx][index].addend; - return glue(glue(ld, USUFFIX), _raw)((uint8_t *)haddr); + return glue(glue(ld, LSUFFIX), _raw)((uint8_t *)haddr); } DATA_TYPE @@ -264,6 +264,6 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, #undef SHIFT #undef DATA_TYPE #undef SUFFIX -#undef USUFFIX +#undef LSUFFIX #undef DATA_SIZE #undef ADDR_READ From b1669e5e321a0a96a07ec1f7a82ce8f4b25ddfd5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Aug 2013 13:03:27 -0700 Subject: [PATCH 26/29] target: Include softmmu_exec.h where forgotten Several targets forgot to include softmmu_exec.h, which would break them with a header cleanup to follow. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- target-lm32/op_helper.c | 2 ++ target-moxie/helper.c | 1 + target-ppc/mmu_helper.c | 2 ++ target-unicore32/op_helper.c | 2 ++ target-xtensa/op_helper.c | 1 + 5 files changed, 8 insertions(+) diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c index 2dab9f27b4..8f5ef554d5 100644 --- a/target-lm32/op_helper.c +++ b/target-lm32/op_helper.c @@ -6,6 +6,8 @@ #include "hw/lm32/lm32_pic.h" #include "hw/char/lm32_juart.h" +#include "exec/softmmu_exec.h" + #if !defined(CONFIG_USER_ONLY) #define MMUSUFFIX _mmu #define SHIFT 0 diff --git a/target-moxie/helper.c b/target-moxie/helper.c index b12e4ffcaf..7859102ab7 100644 --- a/target-moxie/helper.c +++ b/target-moxie/helper.c @@ -25,6 +25,7 @@ #include "cpu.h" #include "mmu.h" #include "exec/exec-all.h" +#include "exec/softmmu_exec.h" #include "qemu/host-utils.h" #include "helper.h" diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 5dd4e05f78..44f04e5d8b 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -2871,6 +2871,8 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type) /*****************************************************************************/ +#include "exec/softmmu_exec.h" + #define MMUSUFFIX _mmu #define SHIFT 0 diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c index 6443ffec1c..4f9f41eb36 100644 --- a/target-unicore32/op_helper.c +++ b/target-unicore32/op_helper.c @@ -239,6 +239,8 @@ uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i) } #ifndef CONFIG_USER_ONLY +#include "exec/softmmu_exec.h" + #define MMUSUFFIX _mmu #define SHIFT 0 diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 01123af707..cf970257db 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -28,6 +28,7 @@ #include "cpu.h" #include "helper.h" #include "qemu/host-utils.h" +#include "exec/softmmu_exec.h" static void do_unaligned_access(CPUXtensaState *env, target_ulong addr, int is_write, int is_user, uintptr_t retaddr); From e58eb534133f8ccaa957a33a06ccdb9129f2c842 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Aug 2013 13:13:44 -0700 Subject: [PATCH 27/29] exec: Split softmmu_defs.h The _cmmu helpers can be moved to exec-all.h. The helpers that are used from TCG will shortly need access to tcg_target_long so move their declarations into tcg.h. This requires minor include adjustments to all TCG backends. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- include/exec/exec-all.h | 5 +++- include/exec/softmmu_defs.h | 49 ------------------------------------- include/exec/softmmu_exec.h | 3 ++- tcg/aarch64/tcg-target.c | 2 -- tcg/arm/tcg-target.c | 2 -- tcg/hppa/tcg-target.c | 2 -- tcg/i386/tcg-target.c | 3 --- tcg/ia64/tcg-target.c | 3 --- tcg/mips/tcg-target.c | 3 --- tcg/ppc/tcg-target.c | 2 -- tcg/ppc64/tcg-target.c | 3 --- tcg/s390/tcg-target.c | 3 --- tcg/sparc/tcg-target.c | 2 -- tcg/tcg.h | 43 ++++++++++++++++++++++++++++++++ 14 files changed, 49 insertions(+), 76 deletions(-) delete mode 100644 include/exec/softmmu_defs.h diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 6f71a4fdae..beb41491b4 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -377,7 +377,10 @@ bool io_mem_write(struct MemoryRegion *mr, hwaddr addr, void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr); -#include "exec/softmmu_defs.h" +uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); +uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); +uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); +uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); #define ACCESS_TYPE (NB_MMU_MODES + 1) #define MEMSUFFIX _code diff --git a/include/exec/softmmu_defs.h b/include/exec/softmmu_defs.h deleted file mode 100644 index e55e7178c6..0000000000 --- a/include/exec/softmmu_defs.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Software MMU support - * - * Declare helpers used by TCG for qemu_ld/st ops. - * - * Used by softmmu_exec.h, TCG targets and exec-all.h. - * - */ -#ifndef SOFTMMU_DEFS_H -#define SOFTMMU_DEFS_H - -uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); -uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); -uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); -uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); - -void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val, - int mmu_idx, uintptr_t retaddr); -void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val, - int mmu_idx, uintptr_t retaddr); -void helper_ret_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val, - int mmu_idx, uintptr_t retaddr); -void helper_ret_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val, - int mmu_idx, uintptr_t retaddr); - -uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); - -void helper_stb_mmu(CPUArchState *env, target_ulong addr, - uint8_t val, int mmu_idx); -void helper_stw_mmu(CPUArchState *env, target_ulong addr, - uint16_t val, int mmu_idx); -void helper_stl_mmu(CPUArchState *env, target_ulong addr, - uint32_t val, int mmu_idx); -void helper_stq_mmu(CPUArchState *env, target_ulong addr, - uint64_t val, int mmu_idx); - -uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); - -#endif /* SOFTMMU_DEFS_H */ diff --git a/include/exec/softmmu_exec.h b/include/exec/softmmu_exec.h index 3e4e886a30..6fde154527 100644 --- a/include/exec/softmmu_exec.h +++ b/include/exec/softmmu_exec.h @@ -19,7 +19,8 @@ #define ldul_executive ldl_executive #define ldul_supervisor ldl_supervisor -#include "exec/softmmu_defs.h" +/* The memory helpers for tcg-generated code need tcg_target_long etc. */ +#include "tcg.h" #define ACCESS_TYPE 0 #define MEMSUFFIX MMU_MODE0_SUFFIX diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index c472a4aeb4..6379df1f68 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -778,8 +778,6 @@ static inline void tcg_out_nop(TCGContext *s) } #ifdef CONFIG_SOFTMMU -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 5d2db3648b..eb0e84ce44 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1058,8 +1058,6 @@ static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index) #ifdef CONFIG_SOFTMMU -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index 0150e62c8d..236b39c31f 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -910,8 +910,6 @@ static void tcg_out_movcond(TCGContext *s, int cond, TCGArg ret, } #if defined(CONFIG_SOFTMMU) -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 28ed55a096..a0cfe88bca 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1021,9 +1021,6 @@ static void tcg_out_jmp(TCGContext *s, uintptr_t dest) } #if defined(CONFIG_SOFTMMU) - -#include "exec/softmmu_defs.h" - /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, * int mmu_idx, uintptr_t ra) */ diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 0a3ff70025..cd4f1ae1db 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -1490,9 +1490,6 @@ static inline void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGArg ret, } #if defined(CONFIG_SOFTMMU) - -#include "exec/softmmu_defs.h" - /* Load and compare a TLB entry, and return the result in (p6, p7). R2 is loaded with the address of the addend TLB entry. R57 is loaded with the address, zero extented on 32-bit targets. */ diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 6bf7dba82d..3c2b394753 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -919,9 +919,6 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret, } #if defined(CONFIG_SOFTMMU) - -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index f45ce7ce84..25955563b8 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -549,8 +549,6 @@ static void add_qemu_ldst_label (TCGContext *s, label->label_ptr[0] = label_ptr; } -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index c5cfe828f1..0bd1e0ce8c 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -750,9 +750,6 @@ static void tcg_out_ldsta(TCGContext *s, TCGReg ret, TCGReg addr, } #if defined (CONFIG_SOFTMMU) - -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index a1dcb3d826..1b44aeee96 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -315,9 +315,6 @@ static const uint8_t tcg_cond_to_ltr_cond[] = { }; #ifdef CONFIG_SOFTMMU - -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 5eb8c7633f..9574954ac4 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -831,8 +831,6 @@ static void tcg_target_qemu_prologue(TCGContext *s) #if defined(CONFIG_SOFTMMU) -#include "exec/softmmu_defs.h" - /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, int mmu_idx) */ static const void * const qemu_ld_helpers[4] = { diff --git a/tcg/tcg.h b/tcg/tcg.h index d27df66f8d..30ec952bf0 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -21,6 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + +#ifndef TCG_H +#define TCG_H + #include "qemu-common.h" #include "tcg-target.h" @@ -745,3 +749,42 @@ void tcg_register_jit(void *buf, size_t buf_size); /* Generate TB finalization at the end of block */ void tcg_out_tb_finalize(TCGContext *s); #endif + +/* + * Memory helpers that will be used by TCG generated code. + */ +#ifdef CONFIG_SOFTMMU +uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); + +void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val, + int mmu_idx, uintptr_t retaddr); +void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val, + int mmu_idx, uintptr_t retaddr); +void helper_ret_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val, + int mmu_idx, uintptr_t retaddr); +void helper_ret_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val, + int mmu_idx, uintptr_t retaddr); + +uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); +uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); +uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); +uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); + +void helper_stb_mmu(CPUArchState *env, target_ulong addr, + uint8_t val, int mmu_idx); +void helper_stw_mmu(CPUArchState *env, target_ulong addr, + uint16_t val, int mmu_idx); +void helper_stl_mmu(CPUArchState *env, target_ulong addr, + uint32_t val, int mmu_idx); +void helper_stq_mmu(CPUArchState *env, target_ulong addr, + uint64_t val, int mmu_idx); +#endif /* CONFIG_SOFTMMU */ + +#endif /* TCG_H */ From c8f94df5934afd9b2011773aaee0fdef714ff573 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Aug 2013 14:09:14 -0700 Subject: [PATCH 28/29] tcg: Introduce zero and sign-extended versions of load helpers Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- include/exec/softmmu_template.h | 58 ++++++++++++++++++++++++++------- tcg/i386/tcg-target.c | 6 ++-- tcg/tcg.h | 21 ++++++++---- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h index f9922e2689..5bbc56afd5 100644 --- a/include/exec/softmmu_template.h +++ b/include/exec/softmmu_template.h @@ -29,23 +29,39 @@ #if DATA_SIZE == 8 #define SUFFIX q #define LSUFFIX q -#define DATA_TYPE uint64_t +#define SDATA_TYPE int64_t #elif DATA_SIZE == 4 #define SUFFIX l #define LSUFFIX l -#define DATA_TYPE uint32_t +#define SDATA_TYPE int32_t #elif DATA_SIZE == 2 #define SUFFIX w #define LSUFFIX uw -#define DATA_TYPE uint16_t +#define SDATA_TYPE int16_t #elif DATA_SIZE == 1 #define SUFFIX b #define LSUFFIX ub -#define DATA_TYPE uint8_t +#define SDATA_TYPE int8_t #else #error unsupported data size #endif +#define DATA_TYPE glue(u, SDATA_TYPE) + +/* For the benefit of TCG generated code, we want to avoid the complication + of ABI-specific return type promotion and always return a value extended + to the register size of the host. This is tcg_target_long, except in the + case of a 32-bit host and 64-bit data, and for that we always have + uint64_t. Don't bother with this widened value for SOFTMMU_CODE_ACCESS. */ +#if defined(SOFTMMU_CODE_ACCESS) || DATA_SIZE == 8 +# define WORD_TYPE DATA_TYPE +# define USUFFIX SUFFIX +#else +# define WORD_TYPE tcg_target_ulong +# define USUFFIX glue(u, SUFFIX) +# define SSUFFIX glue(s, SUFFIX) +#endif + #ifdef SOFTMMU_CODE_ACCESS #define READ_ACCESS_TYPE 2 #define ADDR_READ addr_code @@ -77,10 +93,10 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, #ifdef SOFTMMU_CODE_ACCESS static #endif -DATA_TYPE -glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, - target_ulong addr, int mmu_idx, - uintptr_t retaddr) +WORD_TYPE +glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(CPUArchState *env, + target_ulong addr, int mmu_idx, + uintptr_t retaddr) { int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; @@ -126,9 +142,9 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, addr2 = addr1 + DATA_SIZE; /* Note the adjustment at the beginning of the function. Undo that for the recursion. */ - res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX) + res1 = glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX) (env, addr1, mmu_idx, retaddr + GETPC_ADJ); - res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX) + res2 = glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX) (env, addr2, mmu_idx, retaddr + GETPC_ADJ); shift = (addr & (DATA_SIZE - 1)) * 8; #ifdef TARGET_WORDS_BIGENDIAN @@ -147,19 +163,33 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, #endif haddr = addr + env->tlb_table[mmu_idx][index].addend; - return glue(glue(ld, LSUFFIX), _raw)((uint8_t *)haddr); + /* Note that ldl_raw is defined with type "int". */ + return (DATA_TYPE) glue(glue(ld, LSUFFIX), _raw)((uint8_t *)haddr); } DATA_TYPE glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, int mmu_idx) { - return glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx, + return glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(env, addr, mmu_idx, GETRA_EXT()); } #ifndef SOFTMMU_CODE_ACCESS +/* Provide signed versions of the load routines as well. We can of course + avoid this for 64-bit data, or for 32-bit data on 32-bit host. */ +#if DATA_SIZE * 8 < TCG_TARGET_REG_BITS +WORD_TYPE +glue(glue(helper_ret_ld, SSUFFIX), MMUSUFFIX)(CPUArchState *env, + target_ulong addr, int mmu_idx, + uintptr_t retaddr) +{ + return (SDATA_TYPE) glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX) + (env, addr, mmu_idx, retaddr); +} +#endif + static inline void glue(io_write, SUFFIX)(CPUArchState *env, hwaddr physaddr, DATA_TYPE val, @@ -267,3 +297,7 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, #undef LSUFFIX #undef DATA_SIZE #undef ADDR_READ +#undef WORD_TYPE +#undef SDATA_TYPE +#undef USUFFIX +#undef SSUFFIX diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index a0cfe88bca..3ee54f18e2 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1025,9 +1025,9 @@ static void tcg_out_jmp(TCGContext *s, uintptr_t dest) * int mmu_idx, uintptr_t ra) */ static const void * const qemu_ld_helpers[4] = { - helper_ret_ldb_mmu, - helper_ret_ldw_mmu, - helper_ret_ldl_mmu, + helper_ret_ldub_mmu, + helper_ret_lduw_mmu, + helper_ret_ldul_mmu, helper_ret_ldq_mmu, }; diff --git a/tcg/tcg.h b/tcg/tcg.h index 30ec952bf0..902c751d26 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -754,15 +754,24 @@ void tcg_out_tb_finalize(TCGContext *s); * Memory helpers that will be used by TCG generated code. */ #ifdef CONFIG_SOFTMMU -uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); -uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); -uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr, - int mmu_idx, uintptr_t retaddr); +/* Value zero-extended to tcg register size. */ +tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +tcg_target_ulong helper_ret_lduw_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +tcg_target_ulong helper_ret_ldul_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx, uintptr_t retaddr); +/* Value sign-extended to tcg register size. */ +tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +tcg_target_ulong helper_ret_ldsw_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +tcg_target_ulong helper_ret_ldsl_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); + void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val, int mmu_idx, uintptr_t retaddr); void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val, From 6fb5874590589585cdcad4ca2431d9d8d4d491b1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 29 Aug 2013 15:00:16 -0700 Subject: [PATCH 29/29] tcg-i386: Make use of zero-extended memory helper routines For 8 and 16-bit unsigned loads, rely on the zero-extension from the helper and use a smaller 32-bit move insn. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 3ee54f18e2..c1f07415ab 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1531,20 +1531,17 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) case 1 | 4: tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW); break; - case 0: - tcg_out_ext8u(s, data_reg, TCG_REG_EAX); - break; - case 1: - tcg_out_ext16u(s, data_reg, TCG_REG_EAX); - break; - case 2: - tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX); - break; #if TCG_TARGET_REG_BITS == 64 case 2 | 4: tcg_out_ext32s(s, data_reg, TCG_REG_EAX); break; #endif + case 0: + case 1: + /* Note that the helpers have zero-extended to tcg_target_long. */ + case 2: + tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX); + break; case 3: if (TCG_TARGET_REG_BITS == 64) { tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);