mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
+13
-5
@@ -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
|
||||
|
||||
|
||||
+22
-26
@@ -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;
|
||||
@@ -180,7 +176,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;
|
||||
@@ -188,7 +184,7 @@ static int tcg_target_const_match(tcg_target_long val,
|
||||
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))) {
|
||||
@@ -1053,7 +1049,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 +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_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 +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_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,
|
||||
@@ -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" } },
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
@@ -79,6 +78,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
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -842,7 +842,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;
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
@@ -109,6 +105,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
|
||||
|
||||
+24
-21
@@ -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;
|
||||
|
||||
@@ -838,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):
|
||||
@@ -1055,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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -95,6 +94,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
|
||||
|
||||
+10
-2
@@ -290,13 +290,21 @@ 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;
|
||||
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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+20
-25
@@ -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 {
|
||||
@@ -515,7 +511,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;
|
||||
@@ -524,8 +520,7 @@ static int tcg_target_const_match(tcg_target_long val,
|
||||
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,
|
||||
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" } },
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -327,14 +327,20 @@ 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;
|
||||
|
||||
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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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 */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user