Pull tcg 2014-04-22

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJTVthUAAoJEK0ScMxN0Ceb5OUH/0Ri4engOQim3mV1jAOr2Vca
 3zg+Hl8b+UioXD0se24Iipr6s+02G1DApbbLPX7DZAnoh9jEBvDtHOdde3pNbMkQ
 jcTpShTyT7OKSsklRN19ckvk0ffBch5W3Ekkw6/Hg6ys2HIvirRpEL6R58oJNlP6
 xcCkQZISZVkakbv5xft8YQo1v8wnU5q2l85OaC1aaDB6g+Y6ZgoA1qkWjqlHkmQk
 1asflfbC0r5ke+yx7vz6310f5xBDLSVv17dqsDUr70o1m/6bem6wQXMczwmYUfk5
 99OCPiqdiCZLJyVFvIvfwSakL9Bq/nvnmywXTkrB7rovk5VZz3gc4sJkuUkL+KM=
 =URV1
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/rth/tags/tcg-next-20140422' into staging

Pull tcg 2014-04-22

# gpg: Signature made Tue 22 Apr 2014 22:00:04 BST using RSA key ID 4DD0279B
# gpg: Can't check signature: public key not found

* remotes/rth/tags/tcg-next-20140422:
  tcg: Use HOST_WORDS_BIGENDIAN
  tcg: Fix fallback from muls2_i64 to mulu2_i64
  tcg: Use tcg_gen_mulu2_i32 in tcg_gen_muls2_i32
  tcg: Relax requirement for mulu2_i32 on 32-bit hosts
  tcg-s390: Remove W constraint
  tcg-sparc: Use the type parameter to tcg_target_const_match
  tcg-ppc64: Use the type parameter to tcg_target_const_match
  tcg-aarch64: Remove w constraint
  tcg: Add TCGType parameter to tcg_target_const_match
  tcg: Fix out of range shift in deposit optimizations
  tci: Mask shift counts to avoid undefined behavior
  tcg: Mask shift quantities while folding
  tcg: Use "unspecified behavior" for shifts
  tcg: Fix warning (1 bit signed bitfield entry) and replace int by bool

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-04-24 15:24:51 +01:00
commit ad600a4d49
26 changed files with 170 additions and 167 deletions

View File

@ -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 A TCG "basic block" corresponds to a list of instructions terminated
by a branch instruction. 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) Intermediate representation
3.1) Introduction 3.1) Introduction
@ -239,23 +245,25 @@ t0=t1|~t2
* shl_i32/i64 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 * 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 * 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 * 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 * 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 ********* Misc

View File

@ -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 0x100
#define TCG_CT_CONST_AIMM 0x200 #define TCG_CT_CONST_LIMM 0x200
#define TCG_CT_CONST_LIMM 0x400 #define TCG_CT_CONST_ZERO 0x400
#define TCG_CT_CONST_ZERO 0x800 #define TCG_CT_CONST_MONE 0x800
#define TCG_CT_CONST_MONE 0x1000
/* parse target specific constraints */ /* parse target specific constraints */
static int target_parse_constraint(TCGArgConstraint *ct, 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); tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3);
#endif #endif
break; 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). */ case 'A': /* Valid for arithmetic immediate (positive or negative). */
ct->ct |= TCG_CT_CONST_AIMM; ct->ct |= TCG_CT_CONST_AIMM;
break; break;
@ -180,7 +176,7 @@ static inline bool is_limm(uint64_t val)
return (val & (val - 1)) == 0; 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) const TCGArgConstraint *arg_ct)
{ {
int ct = arg_ct->ct; int ct = arg_ct->ct;
@ -188,7 +184,7 @@ static int tcg_target_const_match(tcg_target_long val,
if (ct & TCG_CT_CONST) { if (ct & TCG_CT_CONST) {
return 1; return 1;
} }
if (ct & TCG_CT_CONST_IS32) { if (type == TCG_TYPE_I32) {
val = (int32_t)val; val = (int32_t)val;
} }
if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) { if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) {
@ -1053,7 +1049,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
tcg_out_goto(s, (intptr_t)lb->raddr); 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, TCGReg data_reg, TCGReg addr_reg,
int mem_index, int mem_index,
uint8_t *raddr, uint8_t *label_ptr) uint8_t *raddr, uint8_t *label_ptr)
@ -1226,7 +1222,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_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); 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); mem_index, s->code_ptr, label_ptr);
#else /* !CONFIG_SOFTMMU */ #else /* !CONFIG_SOFTMMU */
tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg, tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg,
@ -1243,7 +1239,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_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); 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); mem_index, s->code_ptr, label_ptr);
#else /* !CONFIG_SOFTMMU */ #else /* !CONFIG_SOFTMMU */
tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg,
@ -1663,9 +1659,9 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
{ INDEX_op_st32_i64, { "rZ", "r" } }, { INDEX_op_st32_i64, { "rZ", "r" } },
{ INDEX_op_st_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_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_sub_i64, { "r", "r", "rA" } },
{ INDEX_op_mul_i32, { "r", "r", "r" } }, { INDEX_op_mul_i32, { "r", "r", "r" } },
{ INDEX_op_mul_i64, { "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_rem_i64, { "r", "r", "r" } },
{ INDEX_op_remu_i32, { "r", "r", "r" } }, { INDEX_op_remu_i32, { "r", "r", "r" } },
{ INDEX_op_remu_i64, { "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_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_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_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_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_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_eqv_i64, { "r", "r", "rL" } },
{ INDEX_op_neg_i32, { "r", "r" } }, { 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_rotl_i64, { "r", "r", "ri" } },
{ INDEX_op_rotr_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_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_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_movcond_i64, { "r", "r", "rA", "rZ", "rZ" } },
{ INDEX_op_qemu_ld_i32, { "r", "l" } }, { 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_i32, { "r", "0", "rZ" } },
{ INDEX_op_deposit_i64, { "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_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_sub2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
{ INDEX_op_muluh_i64, { "r", "r", "r" } }, { INDEX_op_muluh_i64, { "r", "r", "r" } },

View File

@ -13,7 +13,6 @@
#ifndef TCG_TARGET_AARCH64 #ifndef TCG_TARGET_AARCH64
#define TCG_TARGET_AARCH64 1 #define TCG_TARGET_AARCH64 1
#undef TCG_TARGET_WORDS_BIGENDIAN
#undef TCG_TARGET_STACK_GROWSUP #undef TCG_TARGET_STACK_GROWSUP
typedef enum { typedef enum {

View File

@ -261,7 +261,7 @@ static inline int check_fit_imm(uint32_t imm)
* mov operand2: values represented with x << (2 * y), x < 0x100 * mov operand2: values represented with x << (2 * y), x < 0x100
* add, sub, eor...: ditto * 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) const TCGArgConstraint *arg_ct)
{ {
int ct; int ct;
@ -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 /* 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 path for a load or store, so that we can later generate the correct
helper code. */ 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 datalo, TCGReg datahi, TCGReg addrlo,
TCGReg addrhi, int mem_index, TCGReg addrhi, int mem_index,
uint8_t *raddr, uint8_t *label_ptr) 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); 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); mem_index, s->code_ptr, label_ptr);
#else /* !CONFIG_SOFTMMU */ #else /* !CONFIG_SOFTMMU */
if (GUEST_BASE) { 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; label_ptr = s->code_ptr;
tcg_out_bl_noaddr(s, COND_NE); 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); mem_index, s->code_ptr, label_ptr);
#else /* !CONFIG_SOFTMMU */ #else /* !CONFIG_SOFTMMU */
if (GUEST_BASE) { if (GUEST_BASE) {

View File

@ -25,7 +25,6 @@
#ifndef TCG_TARGET_ARM #ifndef TCG_TARGET_ARM
#define TCG_TARGET_ARM 1 #define TCG_TARGET_ARM 1
#undef TCG_TARGET_WORDS_BIGENDIAN
#undef TCG_TARGET_STACK_GROWSUP #undef TCG_TARGET_STACK_GROWSUP
typedef enum { typedef enum {
@ -79,6 +78,7 @@ extern bool use_idiv_instructions;
#define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_movcond_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_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0

View File

@ -257,7 +257,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
} }
/* test if a constant matches the constraint */ /* 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) const TCGArgConstraint *arg_ct)
{ {
int ct = arg_ct->ct; int ct = arg_ct->ct;
@ -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 * 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 * 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 datalo, TCGReg datahi,
TCGReg addrlo, TCGReg addrhi, TCGReg addrlo, TCGReg addrhi,
int mem_index, uint8_t *raddr, 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); tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc);
/* Record the current context of a load into ldst label */ /* 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); mem_index, s->code_ptr, label_ptr);
#else #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); tcg_out_qemu_st_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc);
/* Record the current context of a store into ldst label */ /* 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); mem_index, s->code_ptr, label_ptr);
#else #else
{ {

View File

@ -24,8 +24,6 @@
#ifndef TCG_TARGET_I386 #ifndef TCG_TARGET_I386
#define TCG_TARGET_I386 1 #define TCG_TARGET_I386 1
#undef TCG_TARGET_WORDS_BIGENDIAN
#ifdef __x86_64__ #ifdef __x86_64__
# define TCG_TARGET_REG_BITS 64 # define TCG_TARGET_REG_BITS 64
# define TCG_TARGET_NB_REGS 16 # define TCG_TARGET_NB_REGS 16

View File

@ -842,7 +842,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
} }
/* test if a constant matches the constraint */ /* 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) const TCGArgConstraint *arg_ct)
{ {
int ct; int ct;

View File

@ -26,7 +26,7 @@
#include "tcg-be-null.h" #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 # define TCG_NEED_BSWAP 0
#else #else
# define TCG_NEED_BSWAP 1 # define TCG_NEED_BSWAP 1
@ -253,7 +253,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
} }
/* test if a constant matches the constraint */ /* 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) const TCGArgConstraint *arg_ct)
{ {
int ct; int ct;
@ -589,7 +589,7 @@ static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
{ {
(*arg_num) = (*arg_num + 1) & ~1; (*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_high);
tcg_out_call_iarg_reg32(s, arg_num, arg_low); tcg_out_call_iarg_reg32(s, arg_num, arg_low);
#else #else
@ -964,7 +964,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
#if defined(CONFIG_SOFTMMU) #if defined(CONFIG_SOFTMMU)
# if TARGET_LONG_BITS == 64 # if TARGET_LONG_BITS == 64
addr_regh = *args++; addr_regh = *args++;
# if defined(TCG_TARGET_WORDS_BIGENDIAN) # if defined(HOST_WORDS_BIGENDIAN)
addr_memh = 0; addr_memh = 0;
addr_meml = 4; addr_meml = 4;
# else # else
@ -979,7 +979,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
#endif #endif
if (opc == 3) { if (opc == 3) {
#if defined(TCG_TARGET_WORDS_BIGENDIAN) #if defined(HOST_WORDS_BIGENDIAN)
data_reg1 = data_regh; data_reg1 = data_regh;
data_reg2 = data_regl; data_reg2 = data_regl;
#else #else
@ -1152,7 +1152,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
#if defined(CONFIG_SOFTMMU) #if defined(CONFIG_SOFTMMU)
# if TARGET_LONG_BITS == 64 # if TARGET_LONG_BITS == 64
addr_regh = *args++; addr_regh = *args++;
# if defined(TCG_TARGET_WORDS_BIGENDIAN) # if defined(HOST_WORDS_BIGENDIAN)
addr_memh = 0; addr_memh = 0;
addr_meml = 4; addr_meml = 4;
# else # else
@ -1167,7 +1167,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
#endif #endif
if (opc == 3) { if (opc == 3) {
#if defined(TCG_TARGET_WORDS_BIGENDIAN) #if defined(HOST_WORDS_BIGENDIAN)
data_reg1 = data_regh; data_reg1 = data_regh;
data_reg2 = data_regl; data_reg2 = data_regl;
#else #else

View File

@ -26,10 +26,6 @@
#ifndef TCG_TARGET_MIPS #ifndef TCG_TARGET_MIPS
#define TCG_TARGET_MIPS 1 #define TCG_TARGET_MIPS 1
#ifdef __MIPSEB__
# define TCG_TARGET_WORDS_BIGENDIAN
#endif
#define TCG_TARGET_NB_REGS 32 #define TCG_TARGET_NB_REGS 32
typedef enum { typedef enum {
@ -109,6 +105,7 @@ extern bool use_mips32r2_instructions;
#define TCG_TARGET_HAS_orc_i32 0 #define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0 #define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_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_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 1 #define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1 #define TCG_TARGET_HAS_mulsh_i32 1

View File

@ -220,34 +220,34 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
return x ^ y; return x ^ y;
case INDEX_op_shl_i32: case INDEX_op_shl_i32:
return (uint32_t)x << (uint32_t)y; return (uint32_t)x << (y & 31);
case INDEX_op_shl_i64: case INDEX_op_shl_i64:
return (uint64_t)x << (uint64_t)y; return (uint64_t)x << (y & 63);
case INDEX_op_shr_i32: case INDEX_op_shr_i32:
return (uint32_t)x >> (uint32_t)y; return (uint32_t)x >> (y & 31);
case INDEX_op_shr_i64: case INDEX_op_shr_i64:
return (uint64_t)x >> (uint64_t)y; return (uint64_t)x >> (y & 63);
case INDEX_op_sar_i32: case INDEX_op_sar_i32:
return (int32_t)x >> (int32_t)y; return (int32_t)x >> (y & 31);
case INDEX_op_sar_i64: case INDEX_op_sar_i64:
return (int64_t)x >> (int64_t)y; return (int64_t)x >> (y & 63);
case INDEX_op_rotr_i32: case INDEX_op_rotr_i32:
return ror32(x, y); return ror32(x, y & 31);
case INDEX_op_rotr_i64: case INDEX_op_rotr_i64:
return ror64(x, y); return ror64(x, y & 63);
case INDEX_op_rotl_i32: case INDEX_op_rotl_i32:
return rol32(x, y); return rol32(x, y & 31);
case INDEX_op_rotl_i64: case INDEX_op_rotl_i64:
return rol64(x, y); return rol64(x, y & 63);
CASE_OP_32_64(not): CASE_OP_32_64(not):
return ~x; return ~x;
@ -806,29 +806,34 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
case INDEX_op_sar_i32: case INDEX_op_sar_i32:
if (temps[args[2]].state == TCG_TEMP_CONST) { 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; break;
case INDEX_op_sar_i64: case INDEX_op_sar_i64:
if (temps[args[2]].state == TCG_TEMP_CONST) { 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; break;
case INDEX_op_shr_i32: case INDEX_op_shr_i32:
if (temps[args[2]].state == TCG_TEMP_CONST) { 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; break;
case INDEX_op_shr_i64: case INDEX_op_shr_i64:
if (temps[args[2]].state == TCG_TEMP_CONST) { 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; break;
CASE_OP_32_64(shl): CASE_OP_32_64(shl):
if (temps[args[2]].state == TCG_TEMP_CONST) { 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; break;
@ -838,9 +843,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
break; break;
CASE_OP_32_64(deposit): CASE_OP_32_64(deposit):
tmp = ((1ull << args[4]) - 1); mask = deposit64(temps[args[1]].mask, args[3], args[4],
mask = ((temps[args[1]].mask & ~(tmp << args[3])) temps[args[2]].mask);
| ((temps[args[2]].mask & tmp) << args[3]));
break; break;
CASE_OP_32_64(or): CASE_OP_32_64(or):
@ -1055,9 +1059,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
if (temps[args[1]].state == TCG_TEMP_CONST if (temps[args[1]].state == TCG_TEMP_CONST
&& temps[args[2]].state == TCG_TEMP_CONST) { && temps[args[2]].state == TCG_TEMP_CONST) {
s->gen_opc_buf[op_index] = op_to_movi(op); s->gen_opc_buf[op_index] = op_to_movi(op);
tmp = ((1ull << args[4]) - 1); tmp = deposit64(temps[args[1]].val, args[3], args[4],
tmp = (temps[args[1]].val & ~(tmp << args[3])) temps[args[2]].val);
| ((temps[args[2]].val & tmp) << args[3]);
tcg_opt_gen_movi(gen_args, args[0], tmp); tcg_opt_gen_movi(gen_args, args[0], tmp);
gen_args += 2; gen_args += 2;
args += 5; args += 5;

View File

@ -298,7 +298,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
} }
/* test if a constant matches the constraint */ /* 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) const TCGArgConstraint *arg_ct)
{ {
int ct; int ct;
@ -524,7 +524,7 @@ static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg,
#if defined(CONFIG_SOFTMMU) #if defined(CONFIG_SOFTMMU)
static void add_qemu_ldst_label (TCGContext *s, static void add_qemu_ldst_label (TCGContext *s,
int is_ld, bool is_ld,
TCGMemOp opc, TCGMemOp opc,
int data_reg, int data_reg,
int data_reg2, int data_reg2,
@ -720,7 +720,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
break; break;
} }
#ifdef CONFIG_SOFTMMU #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); addrhi, mem_index, s->code_ptr, label_ptr);
#endif #endif
} }
@ -779,7 +779,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
} }
#ifdef CONFIG_SOFTMMU #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); mem_index, s->code_ptr, label_ptr);
#endif #endif
} }

View File

@ -24,7 +24,6 @@
#ifndef TCG_TARGET_PPC #ifndef TCG_TARGET_PPC
#define TCG_TARGET_PPC 1 #define TCG_TARGET_PPC 1
#define TCG_TARGET_WORDS_BIGENDIAN
#define TCG_TARGET_NB_REGS 32 #define TCG_TARGET_NB_REGS 32
typedef enum { typedef enum {
@ -95,6 +94,7 @@ typedef enum {
#define TCG_TARGET_HAS_nor_i32 1 #define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_movcond_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_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0

View File

@ -290,13 +290,21 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
} }
/* test if a constant matches the constraint */ /* 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) const TCGArgConstraint *arg_ct)
{ {
int ct = arg_ct->ct; int ct = arg_ct->ct;
if (ct & TCG_CT_CONST) { if (ct & TCG_CT_CONST) {
return 1; 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; return 1;
} else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) { } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
return 1; return 1;

View File

@ -24,7 +24,6 @@
#ifndef TCG_TARGET_PPC64 #ifndef TCG_TARGET_PPC64
#define TCG_TARGET_PPC64 1 #define TCG_TARGET_PPC64 1
#define TCG_TARGET_WORDS_BIGENDIAN
#define TCG_TARGET_NB_REGS 32 #define TCG_TARGET_NB_REGS 32
typedef enum { typedef enum {

View File

@ -38,11 +38,10 @@
a 32-bit displacement here Just In Case. */ a 32-bit displacement here Just In Case. */
#define USE_LONG_BRANCHES 0 #define USE_LONG_BRANCHES 0
#define TCG_CT_CONST_32 0x0100 #define TCG_CT_CONST_MULI 0x100
#define TCG_CT_CONST_MULI 0x0800 #define TCG_CT_CONST_ORI 0x200
#define TCG_CT_CONST_ORI 0x2000 #define TCG_CT_CONST_XORI 0x400
#define TCG_CT_CONST_XORI 0x4000 #define TCG_CT_CONST_CMPI 0x800
#define TCG_CT_CONST_CMPI 0x8000
/* Several places within the instruction set 0 means "no register" /* Several places within the instruction set 0 means "no register"
rather than TCG_REG_R0. */ 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_clear(ct->u.regs);
tcg_regset_set_reg(ct->u.regs, TCG_REG_R3); tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
break; break;
case 'W': /* force 32-bit ("word") immediate */
ct->ct |= TCG_CT_CONST_32;
break;
case 'K': case 'K':
ct->ct |= TCG_CT_CONST_MULI; ct->ct |= TCG_CT_CONST_MULI;
break; 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 can load efficiently, and the immediate load plus the reg-reg OR is
smaller than the sequential OI's. */ 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 (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. */ /* All 32-bit ORs can be performed with 1 48-bit insn. */
return 1; 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 extended-immediate facility. That said, there are a few patterns for
which it is better to load the value into a register first. */ 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) { if ((facilities & FACILITY_EXT_IMM) == 0) {
return 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. */ /* All 32-bit XORs can be performed with 1 48-bit insn. */
return 1; return 1;
} }
@ -487,11 +483,11 @@ static int tcg_match_xori(int ct, tcg_target_long val)
/* Imediates to be used with comparisons. */ /* 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) { if (facilities & FACILITY_EXT_IMM) {
/* The COMPARE IMMEDIATE instruction is available. */ /* 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. */ /* We have a 32-bit immediate and can compare against anything. */
return 1; return 1;
} else { } else {
@ -515,7 +511,7 @@ static int tcg_match_cmpi(int ct, tcg_target_long val)
} }
/* Test if a constant matches the constraint. */ /* 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) const TCGArgConstraint *arg_ct)
{ {
int ct = arg_ct->ct; int ct = arg_ct->ct;
@ -524,8 +520,7 @@ static int tcg_target_const_match(tcg_target_long val,
return 1; return 1;
} }
/* Handle the modifiers. */ if (type == TCG_TYPE_I32) {
if (ct & TCG_CT_CONST_32) {
val = (int32_t)val; val = (int32_t)val;
} }
@ -541,11 +536,11 @@ static int tcg_target_const_match(tcg_target_long val,
return val == (int16_t)val; return val == (int16_t)val;
} }
} else if (ct & TCG_CT_CONST_ORI) { } 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) { } 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) { } else if (ct & TCG_CT_CONST_CMPI) {
return tcg_match_cmpi(ct, val); return tcg_match_cmpi(type, val);
} }
return 0; return 0;
@ -2112,8 +2107,8 @@ static const TCGTargetOpDef s390_op_defs[] = {
{ INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } }, { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
{ INDEX_op_and_i32, { "r", "0", "ri" } }, { INDEX_op_and_i32, { "r", "0", "ri" } },
{ INDEX_op_or_i32, { "r", "0", "rWO" } }, { INDEX_op_or_i32, { "r", "0", "rO" } },
{ INDEX_op_xor_i32, { "r", "0", "rWX" } }, { INDEX_op_xor_i32, { "r", "0", "rX" } },
{ INDEX_op_neg_i32, { "r", "r" } }, { 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_add2_i32, { "r", "r", "0", "1", "r", "r" } },
{ INDEX_op_sub2_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_brcond_i32, { "r", "rC" } },
{ INDEX_op_setcond_i32, { "r", "r", "rWC" } }, { INDEX_op_setcond_i32, { "r", "r", "rC" } },
{ INDEX_op_movcond_i32, { "r", "r", "rWC", "r", "0" } }, { INDEX_op_movcond_i32, { "r", "r", "rC", "r", "0" } },
{ INDEX_op_deposit_i32, { "r", "0", "r" } }, { INDEX_op_deposit_i32, { "r", "0", "r" } },
{ INDEX_op_qemu_ld8u, { "r", "L" } }, { INDEX_op_qemu_ld8u, { "r", "L" } },

View File

@ -24,8 +24,6 @@
#ifndef TCG_TARGET_S390 #ifndef TCG_TARGET_S390
#define TCG_TARGET_S390 1 #define TCG_TARGET_S390 1
#define TCG_TARGET_WORDS_BIGENDIAN
typedef enum TCGReg { typedef enum TCGReg {
TCG_REG_R0 = 0, TCG_REG_R0 = 0,
TCG_REG_R1, TCG_REG_R1,

View File

@ -327,14 +327,20 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
} }
/* test if a constant matches the constraint */ /* 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) const TCGArgConstraint *arg_ct)
{ {
int ct = arg_ct->ct; int ct = arg_ct->ct;
if (ct & TCG_CT_CONST) { if (ct & TCG_CT_CONST) {
return 1; 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; return 1;
} else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) { } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
return 1; return 1;

View File

@ -32,8 +32,6 @@
# error Unknown pointer size for tcg target # error Unknown pointer size for tcg target
#endif #endif
#define TCG_TARGET_WORDS_BIGENDIAN
#define TCG_TARGET_NB_REGS 32 #define TCG_TARGET_NB_REGS 32
typedef enum { typedef enum {

View File

@ -24,7 +24,7 @@
#define TCG_MAX_QEMU_LDST 640 #define TCG_MAX_QEMU_LDST 640
typedef struct TCGLabelQemuLdst { 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; TCGMemOp opc:4;
TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */ TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */
TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */ TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */

View File

@ -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 /* since arg2 and ret have different types, they cannot be the
same temporary */ 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_HIGH(ret), arg2, offset);
tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4); tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
#else #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, static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2,
tcg_target_long offset) 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_HIGH(arg1), arg2, offset);
tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4); tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
#else #else
@ -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_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
tcg_gen_mov_i32(rl, t); tcg_gen_mov_i32(rl, t);
tcg_temp_free_i32(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 t0 = tcg_temp_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32();
TCGv_i32 t2 = tcg_temp_new_i32(); TCGv_i32 t2 = tcg_temp_new_i32();
TCGv_i32 t3 = tcg_temp_new_i32(); TCGv_i32 t3 = tcg_temp_new_i32();
tcg_gen_op4_i32(INDEX_op_mulu2_i32, t0, t1, arg1, arg2); tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
/* Allow the optimizer room to replace mulu2 with two moves. */
tcg_gen_op0(INDEX_op_nop);
/* Adjust for negative inputs. */ /* Adjust for negative inputs. */
tcg_gen_sari_i32(t2, arg1, 31); tcg_gen_sari_i32(t2, arg1, 31);
tcg_gen_sari_i32(t3, arg2, 31); tcg_gen_sari_i32(t3, arg2, 31);
@ -2522,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_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
tcg_gen_mov_i64(rl, t); tcg_gen_mov_i64(rl, t);
tcg_temp_free_i64(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 { } else {
TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t0 = tcg_temp_new_i64();
int sizemask = 0; int sizemask = 0;
@ -2569,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_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
tcg_gen_mov_i64(rl, t); tcg_gen_mov_i64(rl, t);
tcg_temp_free_i64(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 { } else {
TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t0 = tcg_temp_new_i64();
int sizemask = 0; int sizemask = 0;

View File

@ -101,7 +101,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
const int *const_args); const int *const_args);
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
intptr_t arg2); 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); const TCGArgConstraint *arg_ct);
static void tcg_out_tb_init(TCGContext *s); static void tcg_out_tb_init(TCGContext *s);
static void tcg_out_tb_finalize(TCGContext *s); static void tcg_out_tb_finalize(TCGContext *s);
@ -444,7 +444,7 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg,
ts->fixed_reg = 0; ts->fixed_reg = 0;
ts->mem_allocated = 1; ts->mem_allocated = 1;
ts->mem_reg = reg; ts->mem_reg = reg;
#ifdef TCG_TARGET_WORDS_BIGENDIAN #ifdef HOST_WORDS_BIGENDIAN
ts->mem_offset = offset + 4; ts->mem_offset = offset + 4;
#else #else
ts->mem_offset = offset; 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->fixed_reg = 0;
ts->mem_allocated = 1; ts->mem_allocated = 1;
ts->mem_reg = reg; ts->mem_reg = reg;
#ifdef TCG_TARGET_WORDS_BIGENDIAN #ifdef HOST_WORDS_BIGENDIAN
ts->mem_offset = offset; ts->mem_offset = offset;
#else #else
ts->mem_offset = offset + 4; 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 (ret != TCG_CALL_DUMMY_ARG) {
#if TCG_TARGET_REG_BITS < 64 #if TCG_TARGET_REG_BITS < 64
if (sizemask & 1) { if (sizemask & 1) {
#ifdef TCG_TARGET_WORDS_BIGENDIAN #ifdef HOST_WORDS_BIGENDIAN
*s->gen_opparam_ptr++ = ret + 1; *s->gen_opparam_ptr++ = ret + 1;
*s->gen_opparam_ptr++ = ret; *s->gen_opparam_ptr++ = ret;
#else #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 order. If another such target is added, this logic may
have to get more complicated to differentiate between have to get more complicated to differentiate between
stack arguments and register arguments. */ 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] + 1;
*s->gen_opparam_ptr++ = args[i]; *s->gen_opparam_ptr++ = args[i];
#else #else
@ -2121,7 +2121,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
ts->mem_coherent = 1; ts->mem_coherent = 1;
s->reg_to_temp[reg] = arg; s->reg_to_temp[reg] = arg;
} else if (ts->val_type == TEMP_VAL_CONST) { } 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 */ /* constant is OK for instruction */
const_args[i] = 1; const_args[i] = 1;
new_args[i] = ts->val; new_args[i] = ts->val;
@ -2365,7 +2365,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
func_arg = reg; func_arg = reg;
tcg_regset_set_reg(allocated_regs, reg); tcg_regset_set_reg(allocated_regs, reg);
} else if (ts->val_type == TEMP_VAL_CONST) { } 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; const_func_arg = 1;
func_arg = func_addr; func_arg = func_addr;
} else { } else {

View File

@ -97,7 +97,6 @@ typedef uint64_t TCGRegSet;
/* Turn some undef macros into true macros. */ /* Turn some undef macros into true macros. */
#define TCG_TARGET_HAS_add2_i32 1 #define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1 #define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#endif #endif
#ifndef TCG_TARGET_deposit_i32_valid #ifndef TCG_TARGET_deposit_i32_valid
@ -121,6 +120,13 @@ typedef uint64_t TCGRegSet;
#define TCG_TARGET_HAS_rem_i64 0 #define TCG_TARGET_HAS_rem_i64 0
#endif #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 { typedef enum TCGOpcode {
#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name, #define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
#include "tcg-opc.h" #include "tcg-opc.h"

View File

@ -859,7 +859,7 @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
} }
/* Test if a constant matches the constraint. */ /* 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) const TCGArgConstraint *arg_ct)
{ {
/* No need to return 0 or 1, 0 or != 0 is good enough. */ /* No need to return 0 or 1, 0 or != 0 is good enough. */

View File

@ -57,12 +57,6 @@
#define CONFIG_DEBUG_TCG_INTERPRETER #define CONFIG_DEBUG_TCG_INTERPRETER
#endif #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. */ /* Optional instructions. */
#define TCG_TARGET_HAS_bswap16_i32 1 #define TCG_TARGET_HAS_bswap16_i32 1
@ -118,6 +112,8 @@
#define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muluh_i64 0 #define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0 #define TCG_TARGET_HAS_mulsh_i64 0
#else
#define TCG_TARGET_HAS_mulu2_i32 1
#endif /* TCG_TARGET_REG_BITS == 64 */ #endif /* TCG_TARGET_REG_BITS == 64 */
#define TCG_TARGET_HAS_new_ldst 0 #define TCG_TARGET_HAS_new_ldst 0

20
tci.c
View File

@ -669,32 +669,32 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri32(&tb_ptr); t1 = tci_read_ri32(&tb_ptr);
t2 = 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; break;
case INDEX_op_shr_i32: case INDEX_op_shr_i32:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri32(&tb_ptr); t1 = tci_read_ri32(&tb_ptr);
t2 = 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; break;
case INDEX_op_sar_i32: case INDEX_op_sar_i32:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri32(&tb_ptr); t1 = tci_read_ri32(&tb_ptr);
t2 = 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; break;
#if TCG_TARGET_HAS_rot_i32 #if TCG_TARGET_HAS_rot_i32
case INDEX_op_rotl_i32: case INDEX_op_rotl_i32:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri32(&tb_ptr); t1 = tci_read_ri32(&tb_ptr);
t2 = 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; break;
case INDEX_op_rotr_i32: case INDEX_op_rotr_i32:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri32(&tb_ptr); t1 = tci_read_ri32(&tb_ptr);
t2 = 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; break;
#endif #endif
#if TCG_TARGET_HAS_deposit_i32 #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++; t0 = *tb_ptr++;
t1 = tci_read_ri64(&tb_ptr); t1 = tci_read_ri64(&tb_ptr);
t2 = 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; break;
case INDEX_op_shr_i64: case INDEX_op_shr_i64:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri64(&tb_ptr); t1 = tci_read_ri64(&tb_ptr);
t2 = 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; break;
case INDEX_op_sar_i64: case INDEX_op_sar_i64:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri64(&tb_ptr); t1 = tci_read_ri64(&tb_ptr);
t2 = 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; break;
#if TCG_TARGET_HAS_rot_i64 #if TCG_TARGET_HAS_rot_i64
case INDEX_op_rotl_i64: case INDEX_op_rotl_i64:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri64(&tb_ptr); t1 = tci_read_ri64(&tb_ptr);
t2 = 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; break;
case INDEX_op_rotr_i64: case INDEX_op_rotr_i64:
t0 = *tb_ptr++; t0 = *tb_ptr++;
t1 = tci_read_ri64(&tb_ptr); t1 = tci_read_ri64(&tb_ptr);
t2 = 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; break;
#endif #endif
#if TCG_TARGET_HAS_deposit_i64 #if TCG_TARGET_HAS_deposit_i64