From ad5171dbd419ffa9e10de766e1c3198f2ae62dfa Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Fri, 21 Feb 2014 18:18:34 +0100 Subject: [PATCH 01/14] tcg: Fix warning (1 bit signed bitfield entry) and replace int by bool Static code analyzers complain about signed bitfields with only a single bit. is_ld is used as a boolean value, so make it bool. ppc64 already used bool for the 2nd argument is_ld of the local function add_qemu_ldst_label. Modify all other TCG targets to do follow this example. Signed-off-by: Stefan Weil Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 6 +++--- tcg/arm/tcg-target.c | 6 +++--- tcg/i386/tcg-target.c | 6 +++--- tcg/ppc/tcg-target.c | 6 +++--- tcg/tcg-be-ldst.h | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 73ed658aef..d5500fffdc 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -1053,7 +1053,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_goto(s, (intptr_t)lb->raddr); } -static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, TCGReg data_reg, TCGReg addr_reg, int mem_index, uint8_t *raddr, uint8_t *label_ptr) @@ -1226,7 +1226,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 1); tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg, TCG_REG_X1); - add_qemu_ldst_label(s, 1, memop, data_reg, addr_reg, + add_qemu_ldst_label(s, true, memop, data_reg, addr_reg, mem_index, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg, @@ -1243,7 +1243,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 0); tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, TCG_REG_X1); - add_qemu_ldst_label(s, 0, memop, data_reg, addr_reg, + add_qemu_ldst_label(s, false, memop, data_reg, addr_reg, mem_index, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index a65fc658e1..5a092263f1 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1253,7 +1253,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi, /* Record the context of a call to the out of line helper code for the slow path for a load or store, so that we can later generate the correct helper code. */ -static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, TCGReg datalo, TCGReg datahi, TCGReg addrlo, TCGReg addrhi, int mem_index, uint8_t *raddr, uint8_t *label_ptr) @@ -1519,7 +1519,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) tcg_out_qemu_ld_index(s, opc, datalo, datahi, addrlo, addend); - add_qemu_ldst_label(s, 1, opc, datalo, datahi, addrlo, addrhi, + add_qemu_ldst_label(s, true, opc, datalo, datahi, addrlo, addrhi, mem_index, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ if (GUEST_BASE) { @@ -1647,7 +1647,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) label_ptr = s->code_ptr; tcg_out_bl_noaddr(s, COND_NE); - add_qemu_ldst_label(s, 0, opc, datalo, datahi, addrlo, addrhi, + add_qemu_ldst_label(s, false, opc, datalo, datahi, addrlo, addrhi, mem_index, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ if (GUEST_BASE) { diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index f832282d1a..0c2347cc6b 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1244,7 +1244,7 @@ static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi, * Record the context of a call to the out of line helper code for the slow path * for a load or store, so that we can later generate the correct helper code */ -static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOp opc, +static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc, TCGReg datalo, TCGReg datahi, TCGReg addrlo, TCGReg addrhi, int mem_index, uint8_t *raddr, @@ -1554,7 +1554,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc); /* Record the current context of a load into ldst label */ - add_qemu_ldst_label(s, 1, opc, datalo, datahi, addrlo, addrhi, + add_qemu_ldst_label(s, true, opc, datalo, datahi, addrlo, addrhi, mem_index, s->code_ptr, label_ptr); #else { @@ -1685,7 +1685,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) tcg_out_qemu_st_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc); /* Record the current context of a store into ldst label */ - add_qemu_ldst_label(s, 0, opc, datalo, datahi, addrlo, addrhi, + add_qemu_ldst_label(s, false, opc, datalo, datahi, addrlo, addrhi, mem_index, s->code_ptr, label_ptr); #else { diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index dc2c2df890..06bedd9daf 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -524,7 +524,7 @@ static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg, #if defined(CONFIG_SOFTMMU) static void add_qemu_ldst_label (TCGContext *s, - int is_ld, + bool is_ld, TCGMemOp opc, int data_reg, int data_reg2, @@ -720,7 +720,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) break; } #ifdef CONFIG_SOFTMMU - add_qemu_ldst_label(s, 1, opc, datalo, datahi, addrlo, + add_qemu_ldst_label(s, true, opc, datalo, datahi, addrlo, addrhi, mem_index, s->code_ptr, label_ptr); #endif } @@ -779,7 +779,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) } #ifdef CONFIG_SOFTMMU - add_qemu_ldst_label(s, 0, opc, datalo, datahi, addrlo, addrhi, + add_qemu_ldst_label(s, false, opc, datalo, datahi, addrlo, addrhi, mem_index, s->code_ptr, label_ptr); #endif } diff --git a/tcg/tcg-be-ldst.h b/tcg/tcg-be-ldst.h index 284db0c70d..ad94c0ca51 100644 --- a/tcg/tcg-be-ldst.h +++ b/tcg/tcg-be-ldst.h @@ -24,7 +24,7 @@ #define TCG_MAX_QEMU_LDST 640 typedef struct TCGLabelQemuLdst { - int is_ld:1; /* qemu_ld: 1, qemu_st: 0 */ + bool is_ld:1; /* qemu_ld: true, qemu_st: false */ TCGMemOp opc:4; TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */ TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */ From 20022fa15f6a8ddc24a8f9d7d177312fecc7fb3a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 18 Mar 2014 08:21:44 -0700 Subject: [PATCH 02/14] tcg: Use "unspecified behavior" for shifts Change the definition such that shifts are not allowed to crash for any input. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- tcg/README | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tcg/README b/tcg/README index f1782123b7..776e9259e3 100644 --- a/tcg/README +++ b/tcg/README @@ -36,6 +36,12 @@ or a memory location which is stored in a register outside QEMU TBs A TCG "basic block" corresponds to a list of instructions terminated by a branch instruction. +An operation with "undefined behavior" may result in a crash. + +An operation with "unspecified behavior" shall not crash. However, +the result may be one of several possibilities so may be considered +an "undefined result". + 3) Intermediate representation 3.1) Introduction @@ -239,23 +245,25 @@ t0=t1|~t2 * shl_i32/i64 t0, t1, t2 -t0=t1 << t2. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) +t0=t1 << t2. Unspecified behavior if t2 < 0 or t2 >= 32 (resp 64) * shr_i32/i64 t0, t1, t2 -t0=t1 >> t2 (unsigned). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) +t0=t1 >> t2 (unsigned). Unspecified behavior if t2 < 0 or t2 >= 32 (resp 64) * sar_i32/i64 t0, t1, t2 -t0=t1 >> t2 (signed). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) +t0=t1 >> t2 (signed). Unspecified behavior if t2 < 0 or t2 >= 32 (resp 64) * rotl_i32/i64 t0, t1, t2 -Rotation of t2 bits to the left. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) +Rotation of t2 bits to the left. +Unspecified behavior if t2 < 0 or t2 >= 32 (resp 64) * rotr_i32/i64 t0, t1, t2 -Rotation of t2 bits to the right. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64) +Rotation of t2 bits to the right. +Unspecified behavior if t2 < 0 or t2 >= 32 (resp 64) ********* Misc From 50c5c4d12557ede48c573e5138542061acd83500 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 18 Mar 2014 07:45:39 -0700 Subject: [PATCH 03/14] tcg: Mask shift quantities while folding The TCG result would be undefined, but we can at least produce one plausible result and avoid triggering the wrath of analysis tools. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- tcg/optimize.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index 7777743e88..2fb708ed40 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -220,34 +220,34 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) return x ^ y; case INDEX_op_shl_i32: - return (uint32_t)x << (uint32_t)y; + return (uint32_t)x << (y & 31); case INDEX_op_shl_i64: - return (uint64_t)x << (uint64_t)y; + return (uint64_t)x << (y & 63); case INDEX_op_shr_i32: - return (uint32_t)x >> (uint32_t)y; + return (uint32_t)x >> (y & 31); case INDEX_op_shr_i64: - return (uint64_t)x >> (uint64_t)y; + return (uint64_t)x >> (y & 63); case INDEX_op_sar_i32: - return (int32_t)x >> (int32_t)y; + return (int32_t)x >> (y & 31); case INDEX_op_sar_i64: - return (int64_t)x >> (int64_t)y; + return (int64_t)x >> (y & 63); case INDEX_op_rotr_i32: - return ror32(x, y); + return ror32(x, y & 31); case INDEX_op_rotr_i64: - return ror64(x, y); + return ror64(x, y & 63); case INDEX_op_rotl_i32: - return rol32(x, y); + return rol32(x, y & 31); case INDEX_op_rotl_i64: - return rol64(x, y); + return rol64(x, y & 63); CASE_OP_32_64(not): return ~x; @@ -806,29 +806,34 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, case INDEX_op_sar_i32: if (temps[args[2]].state == TCG_TEMP_CONST) { - mask = (int32_t)temps[args[1]].mask >> temps[args[2]].val; + tmp = temps[args[2]].val & 31; + mask = (int32_t)temps[args[1]].mask >> tmp; } break; case INDEX_op_sar_i64: if (temps[args[2]].state == TCG_TEMP_CONST) { - mask = (int64_t)temps[args[1]].mask >> temps[args[2]].val; + tmp = temps[args[2]].val & 63; + mask = (int64_t)temps[args[1]].mask >> tmp; } break; case INDEX_op_shr_i32: if (temps[args[2]].state == TCG_TEMP_CONST) { - mask = (uint32_t)temps[args[1]].mask >> temps[args[2]].val; + tmp = temps[args[2]].val & 31; + mask = (uint32_t)temps[args[1]].mask >> tmp; } break; case INDEX_op_shr_i64: if (temps[args[2]].state == TCG_TEMP_CONST) { - mask = (uint64_t)temps[args[1]].mask >> temps[args[2]].val; + tmp = temps[args[2]].val & 63; + mask = (uint64_t)temps[args[1]].mask >> tmp; } break; CASE_OP_32_64(shl): if (temps[args[2]].state == TCG_TEMP_CONST) { - mask = temps[args[1]].mask << temps[args[2]].val; + tmp = temps[args[2]].val & (TCG_TARGET_REG_BITS - 1); + mask = temps[args[1]].mask << tmp; } break; From 1976cccec8a9965ff3fd6f026783a04f6b4959fd Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 18 Mar 2014 08:44:05 -0700 Subject: [PATCH 04/14] tci: Mask shift counts to avoid undefined behavior TCG now requires unspecified behavior rather than a potential crash, bring the C shift within the letter of the law. Signed-off-by: Richard Henderson --- tci.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tci.c b/tci.c index 0202ed97d1..6523ab82f4 100644 --- a/tci.c +++ b/tci.c @@ -669,32 +669,32 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); - tci_write_reg32(t0, t1 << t2); + tci_write_reg32(t0, t1 << (t2 & 31)); break; case INDEX_op_shr_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); - tci_write_reg32(t0, t1 >> t2); + tci_write_reg32(t0, t1 >> (t2 & 31)); break; case INDEX_op_sar_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); - tci_write_reg32(t0, ((int32_t)t1 >> t2)); + tci_write_reg32(t0, ((int32_t)t1 >> (t2 & 31))); break; #if TCG_TARGET_HAS_rot_i32 case INDEX_op_rotl_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); - tci_write_reg32(t0, rol32(t1, t2)); + tci_write_reg32(t0, rol32(t1, t2 & 31)); break; case INDEX_op_rotr_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); - tci_write_reg32(t0, ror32(t1, t2)); + tci_write_reg32(t0, ror32(t1, t2 & 31)); break; #endif #if TCG_TARGET_HAS_deposit_i32 @@ -936,32 +936,32 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); - tci_write_reg64(t0, t1 << t2); + tci_write_reg64(t0, t1 << (t2 & 63)); break; case INDEX_op_shr_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); - tci_write_reg64(t0, t1 >> t2); + tci_write_reg64(t0, t1 >> (t2 & 63)); break; case INDEX_op_sar_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); - tci_write_reg64(t0, ((int64_t)t1 >> t2)); + tci_write_reg64(t0, ((int64_t)t1 >> (t2 & 63))); break; #if TCG_TARGET_HAS_rot_i64 case INDEX_op_rotl_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); - tci_write_reg64(t0, rol64(t1, t2)); + tci_write_reg64(t0, rol64(t1, t2 & 63)); break; case INDEX_op_rotr_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); - tci_write_reg64(t0, ror64(t1, t2)); + tci_write_reg64(t0, ror64(t1, t2 & 63)); break; #endif #if TCG_TARGET_HAS_deposit_i64 From d998e555d2a504d719b773b3164101aa36284a20 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 18 Mar 2014 14:23:52 -0700 Subject: [PATCH 05/14] tcg: Fix out of range shift in deposit optimizations By inspection, for a deposit(x, y, 0, 64), we'd have a shift of (1<<64) and everything else falls apart. But we can reuse the existing deposit logic to get this right. Signed-off-by: Richard Henderson --- tcg/optimize.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index 2fb708ed40..c447062ab1 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -843,9 +843,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, break; CASE_OP_32_64(deposit): - tmp = ((1ull << args[4]) - 1); - mask = ((temps[args[1]].mask & ~(tmp << args[3])) - | ((temps[args[2]].mask & tmp) << args[3])); + mask = deposit64(temps[args[1]].mask, args[3], args[4], + temps[args[2]].mask); break; CASE_OP_32_64(or): @@ -1060,9 +1059,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, 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); - tmp = ((1ull << args[4]) - 1); - tmp = (temps[args[1]].val & ~(tmp << args[3])) - | ((temps[args[2]].val & tmp) << args[3]); + tmp = deposit64(temps[args[1]].val, args[3], args[4], + temps[args[2]].val); tcg_opt_gen_movi(gen_args, args[0], tmp); gen_args += 2; args += 5; From f6c6afc1d41bf53394df15f62b25f15e1de72614 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 30 Mar 2014 21:22:11 -0700 Subject: [PATCH 06/14] tcg: Add TCGType parameter to tcg_target_const_match Most 64-bit targets need to be able to ignore the high bits of a TCG_TYPE_I32 value. Suggested-by: Stuart Brady Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 2 +- tcg/arm/tcg-target.c | 2 +- tcg/i386/tcg-target.c | 2 +- tcg/ia64/tcg-target.c | 2 +- tcg/mips/tcg-target.c | 2 +- tcg/ppc/tcg-target.c | 2 +- tcg/ppc64/tcg-target.c | 2 +- tcg/s390/tcg-target.c | 2 +- tcg/sparc/tcg-target.c | 2 +- tcg/tcg.c | 6 +++--- tcg/tci/tcg-target.c | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index d5500fffdc..4d2e956bef 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -180,7 +180,7 @@ static inline bool is_limm(uint64_t val) return (val & (val - 1)) == 0; } -static int tcg_target_const_match(tcg_target_long val, +static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct = arg_ct->ct; diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 5a092263f1..7535175f9c 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -261,7 +261,7 @@ static inline int check_fit_imm(uint32_t imm) * mov operand2: values represented with x << (2 * y), x < 0x100 * add, sub, eor...: ditto */ -static inline int tcg_target_const_match(tcg_target_long val, +static inline int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct; diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 0c2347cc6b..34ece1f80b 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -257,7 +257,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) } /* test if a constant matches the constraint */ -static inline int tcg_target_const_match(tcg_target_long val, +static inline int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct = arg_ct->ct; diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 2d8e00cd94..c640184e86 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -832,7 +832,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) } /* test if a constant matches the constraint */ -static inline int tcg_target_const_match(tcg_target_long val, +static inline int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct; diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 40551cdcb5..76bc222642 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -253,7 +253,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) } /* test if a constant matches the constraint */ -static inline int tcg_target_const_match(tcg_target_long val, +static inline int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct; diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 06bedd9daf..83d9340fca 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -298,7 +298,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) } /* test if a constant matches the constraint */ -static int tcg_target_const_match(tcg_target_long val, +static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct; diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 06e440f9bc..a533698aa4 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -290,7 +290,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) } /* test if a constant matches the constraint */ -static int tcg_target_const_match(tcg_target_long val, +static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct = arg_ct->ct; diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 907d9d1744..feeaf970de 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -515,7 +515,7 @@ static int tcg_match_cmpi(int ct, tcg_target_long val) } /* Test if a constant matches the constraint. */ -static int tcg_target_const_match(tcg_target_long val, +static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct = arg_ct->ct; diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 152335cfe1..73121e13cf 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -327,7 +327,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) } /* test if a constant matches the constraint */ -static inline int tcg_target_const_match(tcg_target_long val, +static inline int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { int ct = arg_ct->ct; diff --git a/tcg/tcg.c b/tcg/tcg.c index f1e0763432..d92ecb30e0 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -101,7 +101,7 @@ 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, intptr_t arg2); -static int tcg_target_const_match(tcg_target_long val, +static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct); static void tcg_out_tb_init(TCGContext *s); static void tcg_out_tb_finalize(TCGContext *s); @@ -2121,7 +2121,7 @@ static void tcg_reg_alloc_op(TCGContext *s, ts->mem_coherent = 1; s->reg_to_temp[reg] = arg; } else if (ts->val_type == TEMP_VAL_CONST) { - if (tcg_target_const_match(ts->val, arg_ct)) { + if (tcg_target_const_match(ts->val, ts->type, arg_ct)) { /* constant is OK for instruction */ const_args[i] = 1; new_args[i] = ts->val; @@ -2365,7 +2365,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, func_arg = reg; tcg_regset_set_reg(allocated_regs, reg); } else if (ts->val_type == TEMP_VAL_CONST) { - if (tcg_target_const_match(func_addr, arg_ct)) { + if (tcg_target_const_match(func_addr, ts->type, arg_ct)) { const_func_arg = 1; func_arg = func_addr; } else { diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c index fc80704de8..47c0b85d95 100644 --- a/tcg/tci/tcg-target.c +++ b/tcg/tci/tcg-target.c @@ -859,7 +859,7 @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, } /* Test if a constant matches the constraint. */ -static int tcg_target_const_match(tcg_target_long val, +static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct) { /* No need to return 0 or 1, 0 or != 0 is good enough. */ From 170bf9315b352ce56aafa9785eea441b326ed5b7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 30 Mar 2014 21:26:34 -0700 Subject: [PATCH 07/14] tcg-aarch64: Remove w constraint Now redundant with the type parameter to tcg_target_const_match. Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 4d2e956bef..0a580b65ea 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -102,11 +102,10 @@ static inline void patch_reloc(uint8_t *code_ptr, int type, } } -#define TCG_CT_CONST_IS32 0x100 -#define TCG_CT_CONST_AIMM 0x200 -#define TCG_CT_CONST_LIMM 0x400 -#define TCG_CT_CONST_ZERO 0x800 -#define TCG_CT_CONST_MONE 0x1000 +#define TCG_CT_CONST_AIMM 0x100 +#define TCG_CT_CONST_LIMM 0x200 +#define TCG_CT_CONST_ZERO 0x400 +#define TCG_CT_CONST_MONE 0x800 /* parse target specific constraints */ static int target_parse_constraint(TCGArgConstraint *ct, @@ -131,9 +130,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3); #endif break; - case 'w': /* The operand should be considered 32-bit. */ - ct->ct |= TCG_CT_CONST_IS32; - break; case 'A': /* Valid for arithmetic immediate (positive or negative). */ ct->ct |= TCG_CT_CONST_AIMM; break; @@ -188,7 +184,7 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type, if (ct & TCG_CT_CONST) { return 1; } - if (ct & TCG_CT_CONST_IS32) { + if (type == TCG_TYPE_I32) { val = (int32_t)val; } if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) { @@ -1663,9 +1659,9 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_st32_i64, { "rZ", "r" } }, { INDEX_op_st_i64, { "rZ", "r" } }, - { INDEX_op_add_i32, { "r", "r", "rwA" } }, + { INDEX_op_add_i32, { "r", "r", "rA" } }, { INDEX_op_add_i64, { "r", "r", "rA" } }, - { INDEX_op_sub_i32, { "r", "r", "rwA" } }, + { INDEX_op_sub_i32, { "r", "r", "rA" } }, { INDEX_op_sub_i64, { "r", "r", "rA" } }, { INDEX_op_mul_i32, { "r", "r", "r" } }, { INDEX_op_mul_i64, { "r", "r", "r" } }, @@ -1677,17 +1673,17 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_rem_i64, { "r", "r", "r" } }, { INDEX_op_remu_i32, { "r", "r", "r" } }, { INDEX_op_remu_i64, { "r", "r", "r" } }, - { INDEX_op_and_i32, { "r", "r", "rwL" } }, + { INDEX_op_and_i32, { "r", "r", "rL" } }, { INDEX_op_and_i64, { "r", "r", "rL" } }, - { INDEX_op_or_i32, { "r", "r", "rwL" } }, + { INDEX_op_or_i32, { "r", "r", "rL" } }, { INDEX_op_or_i64, { "r", "r", "rL" } }, - { INDEX_op_xor_i32, { "r", "r", "rwL" } }, + { INDEX_op_xor_i32, { "r", "r", "rL" } }, { INDEX_op_xor_i64, { "r", "r", "rL" } }, - { INDEX_op_andc_i32, { "r", "r", "rwL" } }, + { INDEX_op_andc_i32, { "r", "r", "rL" } }, { INDEX_op_andc_i64, { "r", "r", "rL" } }, - { INDEX_op_orc_i32, { "r", "r", "rwL" } }, + { INDEX_op_orc_i32, { "r", "r", "rL" } }, { INDEX_op_orc_i64, { "r", "r", "rL" } }, - { INDEX_op_eqv_i32, { "r", "r", "rwL" } }, + { INDEX_op_eqv_i32, { "r", "r", "rL" } }, { INDEX_op_eqv_i64, { "r", "r", "rL" } }, { INDEX_op_neg_i32, { "r", "r" } }, @@ -1706,11 +1702,11 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_rotl_i64, { "r", "r", "ri" } }, { INDEX_op_rotr_i64, { "r", "r", "ri" } }, - { INDEX_op_brcond_i32, { "r", "rwA" } }, + { INDEX_op_brcond_i32, { "r", "rA" } }, { INDEX_op_brcond_i64, { "r", "rA" } }, - { INDEX_op_setcond_i32, { "r", "r", "rwA" } }, + { INDEX_op_setcond_i32, { "r", "r", "rA" } }, { INDEX_op_setcond_i64, { "r", "r", "rA" } }, - { INDEX_op_movcond_i32, { "r", "r", "rwA", "rZ", "rZ" } }, + { INDEX_op_movcond_i32, { "r", "r", "rA", "rZ", "rZ" } }, { INDEX_op_movcond_i64, { "r", "r", "rA", "rZ", "rZ" } }, { INDEX_op_qemu_ld_i32, { "r", "l" } }, @@ -1739,9 +1735,9 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, { INDEX_op_deposit_i64, { "r", "0", "rZ" } }, - { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rwA", "rwMZ" } }, + { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, { INDEX_op_add2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, - { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rwA", "rwMZ" } }, + { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, { INDEX_op_sub2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, { INDEX_op_muluh_i64, { "r", "r", "r" } }, From 1194dcba22a1dbd9fb797fa087bd8f8ab0cb377e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 30 Mar 2014 22:07:27 -0700 Subject: [PATCH 08/14] tcg-ppc64: Use the type parameter to tcg_target_const_match Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index a533698aa4..45b1c06910 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -296,7 +296,15 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type, int ct = arg_ct->ct; if (ct & TCG_CT_CONST) { return 1; - } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) { + } + + /* The only 32-bit constraint we use aside from + TCG_CT_CONST is TCG_CT_CONST_S16. */ + if (type == TCG_TYPE_I32) { + val = (int32_t)val; + } + + if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) { return 1; } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) { return 1; From 4b304cfae13e66d95de8bb67ce769881fc3a3f1b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 30 Mar 2014 22:27:35 -0700 Subject: [PATCH 09/14] tcg-sparc: Use the type parameter to tcg_target_const_match Signed-off-by: Richard Henderson --- tcg/sparc/tcg-target.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 73121e13cf..35089b82c9 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -334,7 +334,13 @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type, if (ct & TCG_CT_CONST) { return 1; - } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) { + } + + if (type == TCG_TYPE_I32) { + val = (int32_t)val; + } + + if ((ct & TCG_CT_CONST_ZERO) && val == 0) { return 1; } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) { return 1; From 671c835b7dc12bfb3907c6af38f74073fe8fade9 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 31 Mar 2014 02:25:26 -0400 Subject: [PATCH 10/14] tcg-s390: Remove W constraint Now redundant with the type parameter to tcg_target_const_match. Signed-off-by: Richard Henderson --- tcg/s390/tcg-target.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index feeaf970de..1d912a7937 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -38,11 +38,10 @@ a 32-bit displacement here Just In Case. */ #define USE_LONG_BRANCHES 0 -#define TCG_CT_CONST_32 0x0100 -#define TCG_CT_CONST_MULI 0x0800 -#define TCG_CT_CONST_ORI 0x2000 -#define TCG_CT_CONST_XORI 0x4000 -#define TCG_CT_CONST_CMPI 0x8000 +#define TCG_CT_CONST_MULI 0x100 +#define TCG_CT_CONST_ORI 0x200 +#define TCG_CT_CONST_XORI 0x400 +#define TCG_CT_CONST_CMPI 0x800 /* Several places within the instruction set 0 means "no register" rather than TCG_REG_R0. */ @@ -407,9 +406,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) tcg_regset_clear(ct->u.regs); tcg_regset_set_reg(ct->u.regs, TCG_REG_R3); break; - case 'W': /* force 32-bit ("word") immediate */ - ct->ct |= TCG_CT_CONST_32; - break; case 'K': ct->ct |= TCG_CT_CONST_MULI; break; @@ -437,10 +433,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) can load efficiently, and the immediate load plus the reg-reg OR is smaller than the sequential OI's. */ -static int tcg_match_ori(int ct, tcg_target_long val) +static int tcg_match_ori(TCGType type, tcg_target_long val) { if (facilities & FACILITY_EXT_IMM) { - if (ct & TCG_CT_CONST_32) { + if (type == TCG_TYPE_I32) { /* All 32-bit ORs can be performed with 1 48-bit insn. */ return 1; } @@ -466,13 +462,13 @@ static int tcg_match_ori(int ct, tcg_target_long val) extended-immediate facility. That said, there are a few patterns for which it is better to load the value into a register first. */ -static int tcg_match_xori(int ct, tcg_target_long val) +static int tcg_match_xori(TCGType type, tcg_target_long val) { if ((facilities & FACILITY_EXT_IMM) == 0) { return 0; } - if (ct & TCG_CT_CONST_32) { + if (type == TCG_TYPE_I32) { /* All 32-bit XORs can be performed with 1 48-bit insn. */ return 1; } @@ -487,11 +483,11 @@ static int tcg_match_xori(int ct, tcg_target_long val) /* Imediates to be used with comparisons. */ -static int tcg_match_cmpi(int ct, tcg_target_long val) +static int tcg_match_cmpi(TCGType type, tcg_target_long val) { if (facilities & FACILITY_EXT_IMM) { /* The COMPARE IMMEDIATE instruction is available. */ - if (ct & TCG_CT_CONST_32) { + if (type == TCG_TYPE_I32) { /* We have a 32-bit immediate and can compare against anything. */ return 1; } else { @@ -524,8 +520,7 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type, return 1; } - /* Handle the modifiers. */ - if (ct & TCG_CT_CONST_32) { + if (type == TCG_TYPE_I32) { val = (int32_t)val; } @@ -541,11 +536,11 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type, return val == (int16_t)val; } } else if (ct & TCG_CT_CONST_ORI) { - return tcg_match_ori(ct, val); + return tcg_match_ori(type, val); } else if (ct & TCG_CT_CONST_XORI) { - return tcg_match_xori(ct, val); + return tcg_match_xori(type, val); } else if (ct & TCG_CT_CONST_CMPI) { - return tcg_match_cmpi(ct, val); + return tcg_match_cmpi(type, val); } return 0; @@ -2112,8 +2107,8 @@ static const TCGTargetOpDef s390_op_defs[] = { { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } }, { INDEX_op_and_i32, { "r", "0", "ri" } }, - { INDEX_op_or_i32, { "r", "0", "rWO" } }, - { INDEX_op_xor_i32, { "r", "0", "rWX" } }, + { INDEX_op_or_i32, { "r", "0", "rO" } }, + { INDEX_op_xor_i32, { "r", "0", "rX" } }, { INDEX_op_neg_i32, { "r", "r" } }, @@ -2135,9 +2130,9 @@ static const TCGTargetOpDef s390_op_defs[] = { { INDEX_op_add2_i32, { "r", "r", "0", "1", "r", "r" } }, { INDEX_op_sub2_i32, { "r", "r", "0", "1", "r", "r" } }, - { INDEX_op_brcond_i32, { "r", "rWC" } }, - { INDEX_op_setcond_i32, { "r", "r", "rWC" } }, - { INDEX_op_movcond_i32, { "r", "r", "rWC", "r", "0" } }, + { INDEX_op_brcond_i32, { "r", "rC" } }, + { INDEX_op_setcond_i32, { "r", "r", "rC" } }, + { INDEX_op_movcond_i32, { "r", "r", "rC", "r", "0" } }, { INDEX_op_deposit_i32, { "r", "0", "r" } }, { INDEX_op_qemu_ld8u, { "r", "L" } }, From df9ebea53ebc1c98217743f56c30ae3a46031bb9 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 26 Mar 2014 10:59:14 -0700 Subject: [PATCH 11/14] tcg: Relax requirement for mulu2_i32 on 32-bit hosts Instead require either mulu2_i32 or muluh_i32. The code in tcg-op.h already supports looking for both. Previous incomplete conversion? Signed-off-by: Richard Henderson --- tcg/arm/tcg-target.h | 1 + tcg/mips/tcg-target.h | 1 + tcg/ppc/tcg-target.h | 1 + tcg/tcg.h | 8 +++++++- tcg/tci/tcg-target.h | 2 ++ 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 3746b6e298..35de34ede8 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -79,6 +79,7 @@ extern bool use_idiv_instructions; #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_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 diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index 683c6af8b9..c3822d0d4c 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -109,6 +109,7 @@ extern bool use_mips32r2_instructions; #define TCG_TARGET_HAS_orc_i32 0 #define TCG_TARGET_HAS_eqv_i32 0 #define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_mulu2_i32 1 #define TCG_TARGET_HAS_muls2_i32 1 #define TCG_TARGET_HAS_muluh_i32 1 #define TCG_TARGET_HAS_mulsh_i32 1 diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index e3395e301c..11689124d0 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -95,6 +95,7 @@ typedef enum { #define TCG_TARGET_HAS_nor_i32 1 #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_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 diff --git a/tcg/tcg.h b/tcg/tcg.h index f7efcb4202..0bb66775a5 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -97,7 +97,6 @@ typedef uint64_t TCGRegSet; /* Turn some undef macros into true macros. */ #define TCG_TARGET_HAS_add2_i32 1 #define TCG_TARGET_HAS_sub2_i32 1 -#define TCG_TARGET_HAS_mulu2_i32 1 #endif #ifndef TCG_TARGET_deposit_i32_valid @@ -121,6 +120,13 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_rem_i64 0 #endif +/* For 32-bit targets, some sort of unsigned widening multiply is required. */ +#if TCG_TARGET_REG_BITS == 32 \ + && !(defined(TCG_TARGET_HAS_mulu2_i32) \ + || defined(TCG_TARGET_HAS_muluh_i32)) +# error "Missing unsigned widening multiply" +#endif + typedef enum TCGOpcode { #define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name, #include "tcg-opc.h" diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 6e1da8c007..7869119b12 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -118,6 +118,8 @@ #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muluh_i64 0 #define TCG_TARGET_HAS_mulsh_i64 0 +#else +#define TCG_TARGET_HAS_mulu2_i32 1 #endif /* TCG_TARGET_REG_BITS == 64 */ #define TCG_TARGET_HAS_new_ldst 0 From f46fc4e6a953e78b283834f67bc338bd35d7d316 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 26 Mar 2014 11:01:30 -0700 Subject: [PATCH 12/14] tcg: Use tcg_gen_mulu2_i32 in tcg_gen_muls2_i32 Rather than hard-coding use of mulu2_i32, allow muluh_i32. Signed-off-by: Richard Henderson --- tcg/tcg-op.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 7eabf22f01..08dd09e266 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -2437,14 +2437,12 @@ static inline void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, 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) { + } else if (TCG_TARGET_REG_BITS == 32) { TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t2 = tcg_temp_new_i32(); TCGv_i32 t3 = tcg_temp_new_i32(); - tcg_gen_op4_i32(INDEX_op_mulu2_i32, t0, t1, arg1, arg2); - /* Allow the optimizer room to replace mulu2 with two moves. */ - tcg_gen_op0(INDEX_op_nop); + tcg_gen_mulu2_i32(t0, t1, arg1, arg2); /* Adjust for negative inputs. */ tcg_gen_sari_i32(t2, arg1, 31); tcg_gen_sari_i32(t3, arg2, 31); From 662deb908f72a0282c4c2fdb9f62f9f484c62e5b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 26 Mar 2014 11:09:44 -0700 Subject: [PATCH 13/14] tcg: Fix fallback from muls2_i64 to mulu2_i64 Brown Bag sez, don't put the fallback code into the wrong function. Also, check for muluh_i64 and use tcg_gen_mulu2_i64 instead of raw ops. Signed-off-by: Richard Henderson --- tcg/tcg-op.h | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 08dd09e266..d43f45d805 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -2520,26 +2520,6 @@ static inline void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, 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(); - TCGv_i64 t2 = tcg_temp_new_i64(); - TCGv_i64 t3 = tcg_temp_new_i64(); - tcg_gen_op4_i64(INDEX_op_mulu2_i64, t0, t1, arg1, arg2); - /* Allow the optimizer room to replace mulu2 with two moves. */ - tcg_gen_op0(INDEX_op_nop); - /* Adjust for negative inputs. */ - tcg_gen_sari_i64(t2, arg1, 63); - tcg_gen_sari_i64(t3, arg2, 63); - tcg_gen_and_i64(t2, t2, arg2); - tcg_gen_and_i64(t3, t3, arg1); - tcg_gen_sub_i64(rh, t1, t2); - tcg_gen_sub_i64(rh, rh, t3); - tcg_gen_mov_i64(rl, t0); - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); - tcg_temp_free_i64(t2); - tcg_temp_free_i64(t3); } else { TCGv_i64 t0 = tcg_temp_new_i64(); int sizemask = 0; @@ -2567,6 +2547,24 @@ static inline void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2); tcg_gen_mov_i64(rl, t); tcg_temp_free_i64(t); + } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) { + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + TCGv_i64 t2 = tcg_temp_new_i64(); + TCGv_i64 t3 = tcg_temp_new_i64(); + tcg_gen_mulu2_i64(t0, t1, arg1, arg2); + /* Adjust for negative inputs. */ + tcg_gen_sari_i64(t2, arg1, 63); + tcg_gen_sari_i64(t3, arg2, 63); + tcg_gen_and_i64(t2, t2, arg2); + tcg_gen_and_i64(t3, t3, arg1); + tcg_gen_sub_i64(rh, t1, t2); + tcg_gen_sub_i64(rh, rh, t3); + tcg_gen_mov_i64(rl, t0); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + tcg_temp_free_i64(t2); + tcg_temp_free_i64(t3); } else { TCGv_i64 t0 = tcg_temp_new_i64(); int sizemask = 0; From 02eb19d0ec19ac8fb1de1116999184663763eaa0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 31 Mar 2014 14:09:13 -0700 Subject: [PATCH 14/14] tcg: Use HOST_WORDS_BIGENDIAN Instead of rolling a local TCG_TARGET_WORDS_BIGENDIAN. Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.h | 1 - tcg/arm/tcg-target.h | 1 - tcg/i386/tcg-target.h | 2 -- tcg/mips/tcg-target.c | 12 ++++++------ tcg/mips/tcg-target.h | 4 ---- tcg/ppc/tcg-target.h | 1 - tcg/ppc64/tcg-target.h | 1 - tcg/s390/tcg-target.h | 2 -- tcg/sparc/tcg-target.h | 2 -- tcg/tcg-op.h | 4 ++-- tcg/tcg.c | 8 ++++---- tcg/tci/tcg-target.h | 6 ------ 12 files changed, 12 insertions(+), 32 deletions(-) diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index adf02618ec..eff1d68fc6 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -13,7 +13,6 @@ #ifndef TCG_TARGET_AARCH64 #define TCG_TARGET_AARCH64 1 -#undef TCG_TARGET_WORDS_BIGENDIAN #undef TCG_TARGET_STACK_GROWSUP typedef enum { diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 35de34ede8..1bc5dacec0 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -25,7 +25,6 @@ #ifndef TCG_TARGET_ARM #define TCG_TARGET_ARM 1 -#undef TCG_TARGET_WORDS_BIGENDIAN #undef TCG_TARGET_STACK_GROWSUP typedef enum { diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index bdf2222452..ababca0569 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -24,8 +24,6 @@ #ifndef TCG_TARGET_I386 #define TCG_TARGET_I386 1 -#undef TCG_TARGET_WORDS_BIGENDIAN - #ifdef __x86_64__ # define TCG_TARGET_REG_BITS 64 # define TCG_TARGET_NB_REGS 16 diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 76bc222642..37241b224b 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -26,7 +26,7 @@ #include "tcg-be-null.h" -#if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) +#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) # define TCG_NEED_BSWAP 0 #else # define TCG_NEED_BSWAP 1 @@ -589,7 +589,7 @@ static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num, { (*arg_num) = (*arg_num + 1) & ~1; -#if defined(TCG_TARGET_WORDS_BIGENDIAN) +#if defined(HOST_WORDS_BIGENDIAN) tcg_out_call_iarg_reg32(s, arg_num, arg_high); tcg_out_call_iarg_reg32(s, arg_num, arg_low); #else @@ -964,7 +964,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, #if defined(CONFIG_SOFTMMU) # if TARGET_LONG_BITS == 64 addr_regh = *args++; -# if defined(TCG_TARGET_WORDS_BIGENDIAN) +# if defined(HOST_WORDS_BIGENDIAN) addr_memh = 0; addr_meml = 4; # else @@ -979,7 +979,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, #endif if (opc == 3) { -#if defined(TCG_TARGET_WORDS_BIGENDIAN) +#if defined(HOST_WORDS_BIGENDIAN) data_reg1 = data_regh; data_reg2 = data_regl; #else @@ -1152,7 +1152,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, #if defined(CONFIG_SOFTMMU) # if TARGET_LONG_BITS == 64 addr_regh = *args++; -# if defined(TCG_TARGET_WORDS_BIGENDIAN) +# if defined(HOST_WORDS_BIGENDIAN) addr_memh = 0; addr_meml = 4; # else @@ -1167,7 +1167,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, #endif if (opc == 3) { -#if defined(TCG_TARGET_WORDS_BIGENDIAN) +#if defined(HOST_WORDS_BIGENDIAN) data_reg1 = data_regh; data_reg2 = data_regl; #else diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index c3822d0d4c..9576db514d 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -26,10 +26,6 @@ #ifndef TCG_TARGET_MIPS #define TCG_TARGET_MIPS 1 -#ifdef __MIPSEB__ -# define TCG_TARGET_WORDS_BIGENDIAN -#endif - #define TCG_TARGET_NB_REGS 32 typedef enum { diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index 11689124d0..0d4f5959a7 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -24,7 +24,6 @@ #ifndef TCG_TARGET_PPC #define TCG_TARGET_PPC 1 -#define TCG_TARGET_WORDS_BIGENDIAN #define TCG_TARGET_NB_REGS 32 typedef enum { diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h index 7ee50b6c6c..78bbf7a34a 100644 --- a/tcg/ppc64/tcg-target.h +++ b/tcg/ppc64/tcg-target.h @@ -24,7 +24,6 @@ #ifndef TCG_TARGET_PPC64 #define TCG_TARGET_PPC64 1 -#define TCG_TARGET_WORDS_BIGENDIAN #define TCG_TARGET_NB_REGS 32 typedef enum { diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index 10adb778c7..b3bfdcc22c 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -24,8 +24,6 @@ #ifndef TCG_TARGET_S390 #define TCG_TARGET_S390 1 -#define TCG_TARGET_WORDS_BIGENDIAN - typedef enum TCGReg { TCG_REG_R0 = 0, TCG_REG_R1, diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index 3abf1b41b0..4519c64ae9 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -32,8 +32,6 @@ # error Unknown pointer size for tcg target #endif -#define TCG_TARGET_WORDS_BIGENDIAN - #define TCG_TARGET_NB_REGS 32 typedef enum { diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index d43f45d805..8d4ff7da9b 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -858,7 +858,7 @@ static inline void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, { /* since arg2 and ret have different types, they cannot be the same temporary */ -#ifdef TCG_TARGET_WORDS_BIGENDIAN +#ifdef HOST_WORDS_BIGENDIAN tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset); tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4); #else @@ -888,7 +888,7 @@ static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) { -#ifdef TCG_TARGET_WORDS_BIGENDIAN +#ifdef HOST_WORDS_BIGENDIAN tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset); tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4); #else diff --git a/tcg/tcg.c b/tcg/tcg.c index d92ecb30e0..21ce9fb505 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -444,7 +444,7 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg, ts->fixed_reg = 0; ts->mem_allocated = 1; ts->mem_reg = reg; -#ifdef TCG_TARGET_WORDS_BIGENDIAN +#ifdef HOST_WORDS_BIGENDIAN ts->mem_offset = offset + 4; #else ts->mem_offset = offset; @@ -459,7 +459,7 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg, ts->fixed_reg = 0; ts->mem_allocated = 1; ts->mem_reg = reg; -#ifdef TCG_TARGET_WORDS_BIGENDIAN +#ifdef HOST_WORDS_BIGENDIAN ts->mem_offset = offset; #else ts->mem_offset = offset + 4; @@ -686,7 +686,7 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, if (ret != TCG_CALL_DUMMY_ARG) { #if TCG_TARGET_REG_BITS < 64 if (sizemask & 1) { -#ifdef TCG_TARGET_WORDS_BIGENDIAN +#ifdef HOST_WORDS_BIGENDIAN *s->gen_opparam_ptr++ = ret + 1; *s->gen_opparam_ptr++ = ret; #else @@ -725,7 +725,7 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, order. If another such target is added, this logic may have to get more complicated to differentiate between stack arguments and register arguments. */ -#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP) +#if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP) *s->gen_opparam_ptr++ = args[i] + 1; *s->gen_opparam_ptr++ = args[i]; #else diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 7869119b12..f43492cc67 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -57,12 +57,6 @@ #define CONFIG_DEBUG_TCG_INTERPRETER #endif -#if 0 /* TCI tries to emulate a little endian host. */ -#if defined(HOST_WORDS_BIGENDIAN) -# define TCG_TARGET_WORDS_BIGENDIAN -#endif -#endif - /* Optional instructions. */ #define TCG_TARGET_HAS_bswap16_i32 1