* [Qemu-devel] [PATCH 01/10] tcg-mips: fix wrong usage of 'Z' constraint
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 02/10] tcg/mips: kill warnings in user mode Aurelien Jarno
` (9 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
The 'Z' constraint has been introduced to map the zero register. However
when the op also accept a constant, there is no point to accept the zero
register in addition.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 74db83d..9293745 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1453,24 +1453,24 @@ static const TCGTargetOpDef mips_op_defs[] = {
{ INDEX_op_st16_i32, { "rZ", "r" } },
{ INDEX_op_st_i32, { "rZ", "r" } },
- { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
+ { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
{ INDEX_op_div_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
- { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
+ { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
- { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
+ { INDEX_op_and_i32, { "r", "rZ", "rI" } },
{ INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_not_i32, { "r", "rZ" } },
{ INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
{ INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
- { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
- { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
- { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
+ { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
+ { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
+ { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
{ INDEX_op_ext8s_i32, { "r", "rZ" } },
{ INDEX_op_ext16s_i32, { "r", "rZ" } },
@@ -1479,8 +1479,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
{ INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
- { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
- { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
+ { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
+ { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
{ INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
#if TARGET_LONG_BITS == 32
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 02/10] tcg/mips: kill warnings in user mode
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 01/10] tcg-mips: fix wrong usage of 'Z' constraint Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 03/10] tcg/mips: use TCGArg or TCGReg instead of int Aurelien Jarno
` (8 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
Recent versions of GCC emit warnings when compiling user mode targets.
Kill them by reordering a bit the #ifdef.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 84 +++++++++++++++++++++++++------------------------
1 file changed, 43 insertions(+), 41 deletions(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 9293745..a09c0d6 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -842,18 +842,16 @@ static const void * const qemu_st_helpers[4] = {
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
int opc)
{
- int addr_regl, addr_meml;
- int data_regl, data_regh, data_reg1, data_reg2;
- int mem_index, s_bits;
+ int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
#if defined(CONFIG_SOFTMMU)
void *label1_ptr, *label2_ptr;
int arg_num;
-#endif
-#if TARGET_LONG_BITS == 64
-# if defined(CONFIG_SOFTMMU)
+ int mem_index, s_bits;
+ int addr_meml;
+# if TARGET_LONG_BITS == 64
uint8_t *label3_ptr;
-# endif
int addr_regh, addr_memh;
+# endif
#endif
data_regl = *args++;
if (opc == 3)
@@ -861,11 +859,22 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
else
data_regh = 0;
addr_regl = *args++;
-#if TARGET_LONG_BITS == 64
+#if defined(CONFIG_SOFTMMU)
+# if TARGET_LONG_BITS == 64
addr_regh = *args++;
-#endif
+# if defined(TCG_TARGET_WORDS_BIGENDIAN)
+ addr_memh = 0;
+ addr_meml = 4;
+# else
+ addr_memh = 4;
+ addr_meml = 0;
+# endif
+# else
+ addr_meml = 0;
+# endif
mem_index = *args;
s_bits = opc & 3;
+#endif
if (opc == 3) {
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
@@ -879,18 +888,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
data_reg1 = data_regl;
data_reg2 = 0;
}
-#if TARGET_LONG_BITS == 64
-# if defined(TCG_TARGET_WORDS_BIGENDIAN)
- addr_memh = 0;
- addr_meml = 4;
-# else
- addr_memh = 4;
- addr_meml = 0;
-# endif
-#else
- addr_meml = 0;
-#endif
-
#if defined(CONFIG_SOFTMMU)
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
@@ -1029,50 +1026,55 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
int opc)
{
- int addr_regl, addr_meml;
- int data_regl, data_regh, data_reg1, data_reg2;
- int mem_index, s_bits;
+ int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
#if defined(CONFIG_SOFTMMU)
uint8_t *label1_ptr, *label2_ptr;
int arg_num;
+ int mem_index, s_bits;
+ int addr_meml;
#endif
#if TARGET_LONG_BITS == 64
# if defined(CONFIG_SOFTMMU)
uint8_t *label3_ptr;
-# endif
int addr_regh, addr_memh;
+# endif
#endif
-
data_regl = *args++;
if (opc == 3) {
data_regh = *args++;
-#if defined(TCG_TARGET_WORDS_BIGENDIAN)
- data_reg1 = data_regh;
- data_reg2 = data_regl;
-#else
- data_reg1 = data_regl;
- data_reg2 = data_regh;
-#endif
} else {
- data_reg1 = data_regl;
- data_reg2 = 0;
data_regh = 0;
}
addr_regl = *args++;
-#if TARGET_LONG_BITS == 64
+#if defined(CONFIG_SOFTMMU)
+# if TARGET_LONG_BITS == 64
addr_regh = *args++;
-# if defined(TCG_TARGET_WORDS_BIGENDIAN)
+# if defined(TCG_TARGET_WORDS_BIGENDIAN)
addr_memh = 0;
addr_meml = 4;
-# else
+# else
addr_memh = 4;
addr_meml = 0;
-# endif
-#else
+# endif
+# else
addr_meml = 0;
-#endif
+# endif
mem_index = *args;
s_bits = opc;
+#endif
+
+ if (opc == 3) {
+#if defined(TCG_TARGET_WORDS_BIGENDIAN)
+ data_reg1 = data_regh;
+ data_reg2 = data_regl;
+#else
+ data_reg1 = data_regl;
+ data_reg2 = data_regh;
+#endif
+ } else {
+ data_reg1 = data_regl;
+ data_reg2 = 0;
+ }
#if defined(CONFIG_SOFTMMU)
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 03/10] tcg/mips: use TCGArg or TCGReg instead of int
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 01/10] tcg-mips: fix wrong usage of 'Z' constraint Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 02/10] tcg/mips: kill warnings in user mode Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 04/10] tcg/mips: don't use global pointer Aurelien Jarno
` (7 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
Instead of int, use the correct TCGArg and TCGReg type: TCGReg when
representing a TCG target register, TCGArg when representing the latter
or a constant.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 63 +++++++++++++++++++++++++++----------------------
1 file changed, 35 insertions(+), 28 deletions(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index a09c0d6..8b38f98 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -68,7 +68,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
#endif
/* check if we really need so many registers :P */
-static const int tcg_target_reg_alloc_order[] = {
+static const TCGReg tcg_target_reg_alloc_order[] = {
TCG_REG_S0,
TCG_REG_S1,
TCG_REG_S2,
@@ -94,14 +94,14 @@ static const int tcg_target_reg_alloc_order[] = {
TCG_REG_V1
};
-static const int tcg_target_call_iarg_regs[4] = {
+static const TCGReg tcg_target_call_iarg_regs[4] = {
TCG_REG_A0,
TCG_REG_A1,
TCG_REG_A2,
TCG_REG_A3
};
-static const int tcg_target_call_oarg_regs[2] = {
+static const TCGReg tcg_target_call_oarg_regs[2] = {
TCG_REG_V0,
TCG_REG_V1
};
@@ -327,7 +327,8 @@ enum {
/*
* Type reg
*/
-static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
+static inline void tcg_out_opc_reg(TCGContext *s, int opc,
+ TCGReg rd, TCGReg rs, TCGReg rt)
{
int32_t inst;
@@ -341,7 +342,8 @@ static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int r
/*
* Type immediate
*/
-static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
+static inline void tcg_out_opc_imm(TCGContext *s, int opc,
+ TCGReg rt, TCGReg rs, TCGArg imm)
{
int32_t inst;
@@ -355,7 +357,8 @@ static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int i
/*
* Type branch
*/
-static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
+static inline void tcg_out_opc_br(TCGContext *s, int opc,
+ TCGReg rt, TCGReg rs)
{
/* We pay attention here to not modify the branch target by reading
the existing value and using it again. This ensure that caches and
@@ -368,7 +371,8 @@ static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
/*
* Type sa
*/
-static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
+static inline void tcg_out_opc_sa(TCGContext *s, int opc,
+ TCGReg rd, TCGReg rt, TCGArg sa)
{
int32_t inst;
@@ -407,7 +411,7 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
}
}
-static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
+static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
{
/* ret and arg can't be register at */
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
@@ -422,7 +426,7 @@ static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
}
-static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
+static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
{
/* ret and arg can't be register at */
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
@@ -437,7 +441,7 @@ static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
}
-static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
+static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
{
/* ret and arg must be different and can't be register at */
if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
@@ -458,7 +462,7 @@ static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
}
-static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
+static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
{
#ifdef _MIPS_ARCH_MIPS32R2
tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
@@ -468,7 +472,7 @@ static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
#endif
}
-static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
+static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
{
#ifdef _MIPS_ARCH_MIPS32R2
tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
@@ -478,8 +482,8 @@ static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
#endif
}
-static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
- int arg1, tcg_target_long arg2)
+static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
+ TCGReg arg1, TCGArg arg2)
{
if (arg2 == (int16_t) arg2) {
tcg_out_opc_imm(s, opc, arg, arg1, arg2);
@@ -502,7 +506,7 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
}
-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
{
if (val == (int16_t)val) {
tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
@@ -543,7 +547,7 @@ DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
tcg_out_movi(s, TCG_TYPE_I32, A, arg);
-DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, uint32_t arg)
+DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, TCGArg arg)
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
/* We don't use the macro for this one to avoid an unnecessary reg-reg
@@ -573,8 +577,8 @@ static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
#endif
}
-static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
- int arg2, int label_index)
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
+ TCGArg arg2, int label_index)
{
TCGLabel *l = &s->labels[label_index];
@@ -631,8 +635,9 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
/* XXX: we implement it at the target level to avoid having to
handle cross basic blocks temporaries */
-static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
- int arg2, int arg3, int arg4, int label_index)
+static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
+ TCGArg arg2, TCGArg arg3, TCGArg arg4,
+ int label_index)
{
void *label_ptr;
@@ -694,8 +699,8 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
}
-static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
- int arg1, int arg2)
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGArg arg1, TCGArg arg2)
{
switch (cond) {
case TCG_COND_EQ:
@@ -754,8 +759,8 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
/* XXX: we implement it at the target level to avoid having to
handle cross basic blocks temporaries */
-static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
- int arg1, int arg2, int arg3, int arg4)
+static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGArg arg1, TCGArg arg2, TCGArg arg3, TCGArg arg4)
{
switch (cond) {
case TCG_COND_EQ:
@@ -842,7 +847,7 @@ static const void * const qemu_st_helpers[4] = {
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
int opc)
{
- int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
+ TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
#if defined(CONFIG_SOFTMMU)
void *label1_ptr, *label2_ptr;
int arg_num;
@@ -850,7 +855,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
int addr_meml;
# if TARGET_LONG_BITS == 64
uint8_t *label3_ptr;
- int addr_regh, addr_memh;
+ TCGReg addr_regh;
+ int addr_memh;
# endif
#endif
data_regl = *args++;
@@ -1026,7 +1032,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
int opc)
{
- int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
+ TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
#if defined(CONFIG_SOFTMMU)
uint8_t *label1_ptr, *label2_ptr;
int arg_num;
@@ -1036,7 +1042,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
#if TARGET_LONG_BITS == 64
# if defined(CONFIG_SOFTMMU)
uint8_t *label3_ptr;
- int addr_regh, addr_memh;
+ TCGReg addr_regh;
+ int addr_memh;
# endif
#endif
data_regl = *args++;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 04/10] tcg/mips: don't use global pointer
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (2 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 03/10] tcg/mips: use TCGArg or TCGReg instead of int Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 18:18 ` Richard Henderson
2012-09-21 16:43 ` [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps Aurelien Jarno
` (6 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
Don't use the global pointer in TCG, in case helpers try access global
variables.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 8b38f98..0ea6a76 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1529,7 +1529,6 @@ static int tcg_target_callee_save_regs[] = {
TCG_REG_S5,
TCG_REG_S6,
TCG_REG_S7,
- TCG_REG_GP,
TCG_REG_FP,
TCG_REG_RA, /* should be last for ABI compliance */
};
@@ -1595,6 +1594,7 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0); /* internal use */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); /* return address */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
tcg_add_target_add_op_defs(mips_op_defs);
tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 04/10] tcg/mips: don't use global pointer
2012-09-21 16:43 ` [Qemu-devel] [PATCH 04/10] tcg/mips: don't use global pointer Aurelien Jarno
@ 2012-09-21 18:18 ` Richard Henderson
2012-09-21 21:13 ` Aurelien Jarno
0 siblings, 1 reply; 18+ messages in thread
From: Richard Henderson @ 2012-09-21 18:18 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: qemu-devel
On 09/21/2012 09:43 AM, Aurelien Jarno wrote:
> Don't use the global pointer in TCG, in case helpers try access global
> variables.
Err.. isn't the GP computed at the entry point of functions that need to use it?
That said, under n32 and n64 abis it is call-saved; under o32 it's call-clobbered.
So by itself this is still a fix for new-abis, since we don't save it in the
prologue. OTOH, this does suggest an alternate solution... ;-)
r~
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 04/10] tcg/mips: don't use global pointer
2012-09-21 18:18 ` Richard Henderson
@ 2012-09-21 21:13 ` Aurelien Jarno
0 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 21:13 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Fri, Sep 21, 2012 at 11:18:39AM -0700, Richard Henderson wrote:
> On 09/21/2012 09:43 AM, Aurelien Jarno wrote:
> > Don't use the global pointer in TCG, in case helpers try access global
> > variables.
>
> Err.. isn't the GP computed at the entry point of functions that need to use it?
I read that GP should be preserved when checking the MIPS ABI for other
things. But you are right, GCC emit code to recompute GP at the entry point
of the function when used later. I guess I checked the wrong ABI.
> That said, under n32 and n64 abis it is call-saved; under o32 it's call-clobbered.
> So by itself this is still a fix for new-abis, since we don't save it in the
> prologue. OTOH, this does suggest an alternate solution... ;-)
>
Supporting n32 or n64 implies a lot more things than that. So I guess
I'll just drop that patch for now.
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (3 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 04/10] tcg/mips: don't use global pointer Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-22 14:37 ` Blue Swirl
2012-09-21 16:43 ` [Qemu-devel] [PATCH 06/10] tcg/mips: optimize brcond arg, 0 Aurelien Jarno
` (5 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
Use stack instead of temp_buf array in CPUState for TCG
temps.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 0ea6a76..c05169f 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1538,11 +1538,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
{
int i, frame_size;
- /* reserve some stack space */
+ /* reserve some stack space, also for TCG temps. */
frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
- + TCG_STATIC_CALL_ARGS_SIZE;
+ + TCG_STATIC_CALL_ARGS_SIZE
+ + CPU_TEMP_BUF_NLONGS * sizeof(long);
frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
+ tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
+ + TCG_STATIC_CALL_ARGS_SIZE,
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
/* TB prologue */
tcg_out_addi(s, TCG_REG_SP, -frame_size);
@@ -1597,6 +1601,4 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
tcg_add_target_add_op_defs(mips_op_defs);
- tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
- CPU_TEMP_BUF_NLONGS * sizeof(long));
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps
2012-09-21 16:43 ` [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps Aurelien Jarno
@ 2012-09-22 14:37 ` Blue Swirl
2012-09-22 17:25 ` Aurelien Jarno
0 siblings, 1 reply; 18+ messages in thread
From: Blue Swirl @ 2012-09-22 14:37 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: qemu-devel
On Fri, Sep 21, 2012 at 4:43 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Use stack instead of temp_buf array in CPUState for TCG
> temps.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
> tcg/mips/tcg-target.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
> index 0ea6a76..c05169f 100644
> --- a/tcg/mips/tcg-target.c
> +++ b/tcg/mips/tcg-target.c
> @@ -1538,11 +1538,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> {
> int i, frame_size;
>
> - /* reserve some stack space */
> + /* reserve some stack space, also for TCG temps. */
> frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
> - + TCG_STATIC_CALL_ARGS_SIZE;
> + + TCG_STATIC_CALL_ARGS_SIZE
> + + CPU_TEMP_BUF_NLONGS * sizeof(long);
> frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
> ~(TCG_TARGET_STACK_ALIGN - 1);
> + tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
> + + TCG_STATIC_CALL_ARGS_SIZE,
> + CPU_TEMP_BUF_NLONGS * sizeof(long));
My version used frame_size instead of duplicating a part of the
calculations, wouldn't that take stack alignment also in
consideration?
http://lists.nongnu.org/archive/html/qemu-devel/2011-06/msg02566.html
>
> /* TB prologue */
> tcg_out_addi(s, TCG_REG_SP, -frame_size);
> @@ -1597,6 +1601,4 @@ static void tcg_target_init(TCGContext *s)
> tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
>
> tcg_add_target_add_op_defs(mips_op_defs);
> - tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
> - CPU_TEMP_BUF_NLONGS * sizeof(long));
> }
> --
> 1.7.10.4
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps
2012-09-22 14:37 ` Blue Swirl
@ 2012-09-22 17:25 ` Aurelien Jarno
2012-09-22 18:09 ` Blue Swirl
0 siblings, 1 reply; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-22 17:25 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
On Sat, Sep 22, 2012 at 02:37:35PM +0000, Blue Swirl wrote:
> On Fri, Sep 21, 2012 at 4:43 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > Use stack instead of temp_buf array in CPUState for TCG
> > temps.
> >
> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> > ---
> > tcg/mips/tcg-target.c | 10 ++++++----
> > 1 file changed, 6 insertions(+), 4 deletions(-)
> >
> > diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
> > index 0ea6a76..c05169f 100644
> > --- a/tcg/mips/tcg-target.c
> > +++ b/tcg/mips/tcg-target.c
> > @@ -1538,11 +1538,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> > {
> > int i, frame_size;
> >
> > - /* reserve some stack space */
> > + /* reserve some stack space, also for TCG temps. */
> > frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
> > - + TCG_STATIC_CALL_ARGS_SIZE;
> > + + TCG_STATIC_CALL_ARGS_SIZE
> > + + CPU_TEMP_BUF_NLONGS * sizeof(long);
> > frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
> > ~(TCG_TARGET_STACK_ALIGN - 1);
> > + tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
> > + + TCG_STATIC_CALL_ARGS_SIZE,
> > + CPU_TEMP_BUF_NLONGS * sizeof(long));
>
> My version used frame_size instead of duplicating a part of the
> calculations, wouldn't that take stack alignment also in
> consideration?
>
> http://lists.nongnu.org/archive/html/qemu-devel/2011-06/msg02566.html
Oh haven't seen this patch before. Well the choice is basically between
adding one value and subtracting one, not sure what is the best.
About the alignment, do we require some specific alignment for the
temps? As long as they are aligned wrt size, I think it's fine.
> >
> > /* TB prologue */
> > tcg_out_addi(s, TCG_REG_SP, -frame_size);
> > @@ -1597,6 +1601,4 @@ static void tcg_target_init(TCGContext *s)
> > tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
> >
> > tcg_add_target_add_op_defs(mips_op_defs);
> > - tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
> > - CPU_TEMP_BUF_NLONGS * sizeof(long));
> > }
> > --
> > 1.7.10.4
> >
> >
>
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps
2012-09-22 17:25 ` Aurelien Jarno
@ 2012-09-22 18:09 ` Blue Swirl
2012-09-22 18:17 ` Aurelien Jarno
0 siblings, 1 reply; 18+ messages in thread
From: Blue Swirl @ 2012-09-22 18:09 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: qemu-devel
On Sat, Sep 22, 2012 at 5:25 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On Sat, Sep 22, 2012 at 02:37:35PM +0000, Blue Swirl wrote:
>> On Fri, Sep 21, 2012 at 4:43 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
>> > Use stack instead of temp_buf array in CPUState for TCG
>> > temps.
>> >
>> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
>> > ---
>> > tcg/mips/tcg-target.c | 10 ++++++----
>> > 1 file changed, 6 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
>> > index 0ea6a76..c05169f 100644
>> > --- a/tcg/mips/tcg-target.c
>> > +++ b/tcg/mips/tcg-target.c
>> > @@ -1538,11 +1538,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
>> > {
>> > int i, frame_size;
>> >
>> > - /* reserve some stack space */
>> > + /* reserve some stack space, also for TCG temps. */
>> > frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
>> > - + TCG_STATIC_CALL_ARGS_SIZE;
>> > + + TCG_STATIC_CALL_ARGS_SIZE
>> > + + CPU_TEMP_BUF_NLONGS * sizeof(long);
>> > frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
>> > ~(TCG_TARGET_STACK_ALIGN - 1);
>> > + tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
>> > + + TCG_STATIC_CALL_ARGS_SIZE,
>> > + CPU_TEMP_BUF_NLONGS * sizeof(long));
>>
>> My version used frame_size instead of duplicating a part of the
>> calculations, wouldn't that take stack alignment also in
>> consideration?
>>
>> http://lists.nongnu.org/archive/html/qemu-devel/2011-06/msg02566.html
>
> Oh haven't seen this patch before. Well the choice is basically between
> adding one value and subtracting one, not sure what is the best.
>
> About the alignment, do we require some specific alignment for the
> temps? As long as they are aligned wrt size, I think it's fine.
Well, since we align the frame, that could be a better reference.
Usually stack doesn't get unaligned but why is there then the
alignment calculation?
>
>> >
>> > /* TB prologue */
>> > tcg_out_addi(s, TCG_REG_SP, -frame_size);
>> > @@ -1597,6 +1601,4 @@ static void tcg_target_init(TCGContext *s)
>> > tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
>> >
>> > tcg_add_target_add_op_defs(mips_op_defs);
>> > - tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
>> > - CPU_TEMP_BUF_NLONGS * sizeof(long));
>> > }
>> > --
>> > 1.7.10.4
>> >
>> >
>>
>
> --
> Aurelien Jarno GPG: 1024D/F1BCDB73
> aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps
2012-09-22 18:09 ` Blue Swirl
@ 2012-09-22 18:17 ` Aurelien Jarno
0 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-22 18:17 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
On Sat, Sep 22, 2012 at 06:09:13PM +0000, Blue Swirl wrote:
> On Sat, Sep 22, 2012 at 5:25 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > On Sat, Sep 22, 2012 at 02:37:35PM +0000, Blue Swirl wrote:
> >> On Fri, Sep 21, 2012 at 4:43 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> >> > Use stack instead of temp_buf array in CPUState for TCG
> >> > temps.
> >> >
> >> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> >> > ---
> >> > tcg/mips/tcg-target.c | 10 ++++++----
> >> > 1 file changed, 6 insertions(+), 4 deletions(-)
> >> >
> >> > diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
> >> > index 0ea6a76..c05169f 100644
> >> > --- a/tcg/mips/tcg-target.c
> >> > +++ b/tcg/mips/tcg-target.c
> >> > @@ -1538,11 +1538,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> >> > {
> >> > int i, frame_size;
> >> >
> >> > - /* reserve some stack space */
> >> > + /* reserve some stack space, also for TCG temps. */
> >> > frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
> >> > - + TCG_STATIC_CALL_ARGS_SIZE;
> >> > + + TCG_STATIC_CALL_ARGS_SIZE
> >> > + + CPU_TEMP_BUF_NLONGS * sizeof(long);
> >> > frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
> >> > ~(TCG_TARGET_STACK_ALIGN - 1);
> >> > + tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
> >> > + + TCG_STATIC_CALL_ARGS_SIZE,
> >> > + CPU_TEMP_BUF_NLONGS * sizeof(long));
> >>
> >> My version used frame_size instead of duplicating a part of the
> >> calculations, wouldn't that take stack alignment also in
> >> consideration?
> >>
> >> http://lists.nongnu.org/archive/html/qemu-devel/2011-06/msg02566.html
> >
> > Oh haven't seen this patch before. Well the choice is basically between
> > adding one value and subtracting one, not sure what is the best.
> >
> > About the alignment, do we require some specific alignment for the
> > temps? As long as they are aligned wrt size, I think it's fine.
>
> Well, since we align the frame, that could be a better reference.
> Usually stack doesn't get unaligned but why is there then the
> alignment calculation?
>
The ABI require the stack frame to be aligned to 8-bytes. It doesn't
require any alignment for the data you put in the local parts.
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 06/10] tcg/mips: optimize brcond arg, 0
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (4 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 05/10] tcg/mips: use stack for TCG temps Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 07/10] tcg/mips: optimize bswap{16, 16s, 32} on MIPS32R2 Aurelien Jarno
` (4 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
MIPS has some conditional branch instructions when comparing with zero.
Use them.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 38 ++++++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index c05169f..6aa4527 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -278,6 +278,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
enum {
OPC_BEQ = 0x04 << 26,
OPC_BNE = 0x05 << 26,
+ OPC_BLEZ = 0x06 << 26,
+ OPC_BGTZ = 0x07 << 26,
OPC_ADDIU = 0x09 << 26,
OPC_SLTI = 0x0A << 26,
OPC_SLTIU = 0x0B << 26,
@@ -319,6 +321,10 @@ enum {
OPC_SLT = OPC_SPECIAL | 0x2A,
OPC_SLTU = OPC_SPECIAL | 0x2B,
+ OPC_REGIMM = 0x01 << 26,
+ OPC_BLTZ = OPC_REGIMM | (0x00 << 16),
+ OPC_BGEZ = OPC_REGIMM | (0x01 << 16),
+
OPC_SPECIAL3 = 0x1f << 26,
OPC_SEB = OPC_SPECIAL3 | 0x420,
OPC_SEH = OPC_SPECIAL3 | 0x620,
@@ -590,32 +596,48 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
break;
case TCG_COND_LT:
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
- tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
+ if (arg2 == 0) {
+ tcg_out_opc_br(s, OPC_BLTZ, 0, arg1);
+ } else {
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
+ }
break;
case TCG_COND_LTU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_GE:
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
- tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
+ if (arg2 == 0) {
+ tcg_out_opc_br(s, OPC_BGEZ, 0, arg1);
+ } else {
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
+ }
break;
case TCG_COND_GEU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_LE:
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
- tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
+ if (arg2 == 0) {
+ tcg_out_opc_br(s, OPC_BLEZ, 0, arg1);
+ } else {
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
+ }
break;
case TCG_COND_LEU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_GT:
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
- tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
+ if (arg2 == 0) {
+ tcg_out_opc_br(s, OPC_BGTZ, 0, arg1);
+ } else {
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
+ }
break;
case TCG_COND_GTU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 07/10] tcg/mips: optimize bswap{16, 16s, 32} on MIPS32R2
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (5 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 06/10] tcg/mips: optimize brcond arg, 0 Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 08/10] tcg/mips: implement rotl/rotr ops " Aurelien Jarno
` (3 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
bswap operations can be optimized on MIPS32 Release 2 using the ROTR,
WSBH and SEH instructions. We can't use the non-R2 code to implement the
ops due to registers constraints, so don't define the corresponding
TCG_TARGET_HAS_bswap* values.
Also bswap16* operations are supposed to be called with the 16 high bits
zeroed. This is the case everywhere (including for TCG by definition)
except when called from the store helper. Remove the AND instructions from
bswap16* and move it there.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 34 +++++++++++++++++++++++++++++-----
tcg/mips/tcg-target.h | 11 +++++++++--
2 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 6aa4527..8b2f9fc 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -326,6 +326,7 @@ enum {
OPC_BGEZ = OPC_REGIMM | (0x01 << 16),
OPC_SPECIAL3 = 0x1f << 26,
+ OPC_WSBH = OPC_SPECIAL3 | 0x0a0,
OPC_SEB = OPC_SPECIAL3 | 0x420,
OPC_SEH = OPC_SPECIAL3 | 0x620,
};
@@ -419,36 +420,45 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
{
+#ifdef _MIPS_ARCH_MIPS32R2
+ tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+#else
/* ret and arg can't be register at */
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
tcg_abort();
}
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
- tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
-
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+#endif
}
static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
{
+#ifdef _MIPS_ARCH_MIPS32R2
+ tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+ tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
+#else
/* ret and arg can't be register at */
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
tcg_abort();
}
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
- tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
-
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+#endif
}
static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
{
+#ifdef _MIPS_ARCH_MIPS32R2
+ tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+ tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
+#else
/* ret and arg must be different and can't be register at */
if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
tcg_abort();
@@ -466,6 +476,7 @@ static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+#endif
}
static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
@@ -1188,7 +1199,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
break;
case 1:
if (TCG_NEED_BSWAP) {
- tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
+ tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_T0, data_reg1, 0xffff);
+ tcg_out_bswap16(s, TCG_REG_T0, TCG_REG_T0);
tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
} else {
tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
@@ -1409,6 +1421,15 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
break;
+ /* The bswap routines do not work on non-R2 CPU. In that case
+ we let TCG generating the corresponding code. */
+ case INDEX_op_bswap16_i32:
+ tcg_out_bswap16(s, args[0], args[1]);
+ break;
+ case INDEX_op_bswap32_i32:
+ tcg_out_bswap32(s, args[0], args[1]);
+ break;
+
case INDEX_op_ext8s_i32:
tcg_out_ext8s(s, args[0], args[1]);
break;
@@ -1503,6 +1524,9 @@ static const TCGTargetOpDef mips_op_defs[] = {
{ INDEX_op_shr_i32, { "r", "rZ", "ri" } },
{ INDEX_op_sar_i32, { "r", "rZ", "ri" } },
+ { INDEX_op_bswap16_i32, { "r", "r" } },
+ { INDEX_op_bswap32_i32, { "r", "r" } },
+
{ INDEX_op_ext8s_i32, { "r", "rZ" } },
{ INDEX_op_ext16s_i32, { "r", "rZ" } },
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 9c68a32..c5c13f7 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -83,8 +83,6 @@ typedef enum {
#define TCG_TARGET_HAS_rot_i32 0
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
-#define TCG_TARGET_HAS_bswap32_i32 0
-#define TCG_TARGET_HAS_bswap16_i32 0
#define TCG_TARGET_HAS_andc_i32 0
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
@@ -92,6 +90,15 @@ typedef enum {
#define TCG_TARGET_HAS_deposit_i32 0
#define TCG_TARGET_HAS_movcond_i32 0
+/* optional instructions only implemented on MIPS32R2 */
+#ifdef _MIPS_ARCH_MIPS32R2
+#define TCG_TARGET_HAS_bswap16_i32 1
+#define TCG_TARGET_HAS_bswap32_i32 1
+#else
+#define TCG_TARGET_HAS_bswap16_i32 0
+#define TCG_TARGET_HAS_bswap32_i32 0
+#endif
+
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, zero, rt */
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 08/10] tcg/mips: implement rotl/rotr ops on MIPS32R2
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (6 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 07/10] tcg/mips: optimize bswap{16, 16s, 32} on MIPS32R2 Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 09/10] tcg/mips: implement deposit op " Aurelien Jarno
` (2 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
rotr operations can be optimized on MIPS32 Release 2 using the ROTR and
ROTRV instructions. Also implemented rotl operations by subtracting the
shift from 32.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 20 ++++++++++++++++++++
tcg/mips/tcg-target.h | 3 ++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 8b2f9fc..592e42a 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -300,9 +300,11 @@ enum {
OPC_SPECIAL = 0x00 << 26,
OPC_SLL = OPC_SPECIAL | 0x00,
OPC_SRL = OPC_SPECIAL | 0x02,
+ OPC_ROTR = OPC_SPECIAL | (0x01 << 21) | 0x02,
OPC_SRA = OPC_SPECIAL | 0x03,
OPC_SLLV = OPC_SPECIAL | 0x04,
OPC_SRLV = OPC_SPECIAL | 0x06,
+ OPC_ROTRV = OPC_SPECIAL | (0x01 << 6) | 0x06,
OPC_SRAV = OPC_SPECIAL | 0x07,
OPC_JR = OPC_SPECIAL | 0x08,
OPC_JALR = OPC_SPECIAL | 0x09,
@@ -1420,6 +1422,22 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
}
break;
+ case INDEX_op_rotl_i32:
+ if (const_args[2]) {
+ tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], 0x20 - args[2]);
+ } else {
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, 32);
+ tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, TCG_REG_AT, args[2]);
+ tcg_out_opc_reg(s, OPC_ROTRV, args[0], TCG_REG_AT, args[1]);
+ }
+ break;
+ case INDEX_op_rotr_i32:
+ if (const_args[2]) {
+ tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], args[2]);
+ } else {
+ tcg_out_opc_reg(s, OPC_ROTRV, args[0], args[2], args[1]);
+ }
+ break;
/* The bswap routines do not work on non-R2 CPU. In that case
we let TCG generating the corresponding code. */
@@ -1523,6 +1541,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
{ INDEX_op_shl_i32, { "r", "rZ", "ri" } },
{ INDEX_op_shr_i32, { "r", "rZ", "ri" } },
{ INDEX_op_sar_i32, { "r", "rZ", "ri" } },
+ { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
+ { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
{ INDEX_op_bswap16_i32, { "r", "r" } },
{ INDEX_op_bswap32_i32, { "r", "r" } },
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index c5c13f7..470314c 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -80,7 +80,6 @@ typedef enum {
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_nor_i32 1
-#define TCG_TARGET_HAS_rot_i32 0
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_andc_i32 0
@@ -94,9 +93,11 @@ typedef enum {
#ifdef _MIPS_ARCH_MIPS32R2
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
+#define TCG_TARGET_HAS_rot_i32 1
#else
#define TCG_TARGET_HAS_bswap16_i32 0
#define TCG_TARGET_HAS_bswap32_i32 0
+#define TCG_TARGET_HAS_rot_i32 0
#endif
/* optional instructions automatically implemented */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 09/10] tcg/mips: implement deposit op on MIPS32R2
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (7 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 08/10] tcg/mips: implement rotl/rotr ops " Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 16:43 ` [Qemu-devel] [PATCH 10/10] tcg/mips: implement movcond " Aurelien Jarno
2012-09-21 19:33 ` [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Richard Henderson
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
deposit operations can be optimized on MIPS32 Release 2 using the INS
instruction.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 8 ++++++++
tcg/mips/tcg-target.h | 3 ++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 592e42a..b2e1056 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -328,6 +328,7 @@ enum {
OPC_BGEZ = OPC_REGIMM | (0x01 << 16),
OPC_SPECIAL3 = 0x1f << 26,
+ OPC_INS = OPC_SPECIAL3 | 0x004,
OPC_WSBH = OPC_SPECIAL3 | 0x0a0,
OPC_SEB = OPC_SPECIAL3 | 0x420,
OPC_SEH = OPC_SPECIAL3 | 0x620,
@@ -1455,6 +1456,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_ext16s(s, args[0], args[1]);
break;
+ case INDEX_op_deposit_i32:
+ tcg_out_opc_imm(s, OPC_INS, args[0], args[2],
+ ((args[3] + args[4] - 1) << 11) | (args[3] << 6));
+ break;
+
case INDEX_op_brcond_i32:
tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
break;
@@ -1550,6 +1556,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
{ INDEX_op_ext8s_i32, { "r", "rZ" } },
{ INDEX_op_ext16s_i32, { "r", "rZ" } },
+ { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
+
{ INDEX_op_brcond_i32, { "rZ", "rZ" } },
{ INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 470314c..897a737 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -86,7 +86,6 @@ typedef enum {
#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_deposit_i32 0
#define TCG_TARGET_HAS_movcond_i32 0
/* optional instructions only implemented on MIPS32R2 */
@@ -94,10 +93,12 @@ typedef enum {
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_rot_i32 1
+#define TCG_TARGET_HAS_deposit_i32 1
#else
#define TCG_TARGET_HAS_bswap16_i32 0
#define TCG_TARGET_HAS_bswap32_i32 0
#define TCG_TARGET_HAS_rot_i32 0
+#define TCG_TARGET_HAS_deposit_i32 0
#endif
/* optional instructions automatically implemented */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 10/10] tcg/mips: implement movcond op on MIPS32R2
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (8 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 09/10] tcg/mips: implement deposit op " Aurelien Jarno
@ 2012-09-21 16:43 ` Aurelien Jarno
2012-09-21 19:33 ` [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Richard Henderson
10 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-09-21 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Aurelien Jarno
movcond operation can be implemented on MIPS32 Release 2 using the MOVN,
MOVZ, SLT and SLTU instructions.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
tcg/mips/tcg-target.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
tcg/mips/tcg-target.h | 8 ++++++
2 files changed, 77 insertions(+)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index b2e1056..44210e5 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -308,6 +308,8 @@ enum {
OPC_SRAV = OPC_SPECIAL | 0x07,
OPC_JR = OPC_SPECIAL | 0x08,
OPC_JALR = OPC_SPECIAL | 0x09,
+ OPC_MOVZ = OPC_SPECIAL | 0x0A,
+ OPC_MOVN = OPC_SPECIAL | 0x0B,
OPC_MFHI = OPC_SPECIAL | 0x10,
OPC_MFLO = OPC_SPECIAL | 0x12,
OPC_MULT = OPC_SPECIAL | 0x18,
@@ -735,6 +737,68 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
}
+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGArg c1, TCGArg c2, TCGArg v)
+{
+ switch (cond) {
+ case TCG_COND_EQ:
+ if (c1 == 0) {
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c2);
+ } else if (c2 == 0) {
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c1);
+ } else {
+ tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
+ }
+ break;
+ case TCG_COND_NE:
+ if (c1 == 0) {
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, c2);
+ } else if (c2 == 0) {
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, c1);
+ } else {
+ tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
+ }
+ break;
+ case TCG_COND_LT:
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
+ break;
+ case TCG_COND_LTU:
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
+ break;
+ case TCG_COND_GE:
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
+ break;
+ case TCG_COND_GEU:
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
+ break;
+ case TCG_COND_LE:
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
+ break;
+ case TCG_COND_LEU:
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
+ break;
+ case TCG_COND_GT:
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
+ break;
+ case TCG_COND_GTU:
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
+ break;
+ default:
+ tcg_abort();
+ break;
+ }
+}
+
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
TCGArg arg1, TCGArg arg2)
{
@@ -1468,6 +1532,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
break;
+ case INDEX_op_movcond_i32:
+ tcg_out_movcond(s, args[5], args[0], args[1], args[2], args[3]);
+ break;
+
case INDEX_op_setcond_i32:
tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
break;
@@ -1559,6 +1627,7 @@ static const TCGTargetOpDef mips_op_defs[] = {
{ INDEX_op_deposit_i32, { "r", "0", "rZ" } },
{ INDEX_op_brcond_i32, { "rZ", "rZ" } },
+ { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
{ INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
{ INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 897a737..d147e70 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -86,7 +86,15 @@ typedef enum {
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
+
+/* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
+#if defined(_MIPS_ARCH_MIPS4) || defined(_MIPS_ARCH_MIPS32) || \
+ defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_LOONGSON2E) || \
+ defined(_MIPS_ARCH_LOONGSON2F)
+#define TCG_TARGET_HAS_movcond_i32 1
+#else
#define TCG_TARGET_HAS_movcond_i32 0
+#endif
/* optional instructions only implemented on MIPS32R2 */
#ifdef _MIPS_ARCH_MIPS32R2
--
1.7.10.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements
2012-09-21 16:43 [Qemu-devel] [PATCH 00/10] tcg/mips: cleanup and improvements Aurelien Jarno
` (9 preceding siblings ...)
2012-09-21 16:43 ` [Qemu-devel] [PATCH 10/10] tcg/mips: implement movcond " Aurelien Jarno
@ 2012-09-21 19:33 ` Richard Henderson
10 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2012-09-21 19:33 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: qemu-devel
On 09/21/2012 09:43 AM, Aurelien Jarno wrote:
> This patch series first does a bit of cleanup and bug fixing on the
> MIPS TCG backend. Then some optimizations are added, mostly by
> implementing new TCG operations. The last patch depends on the movcond
> series by Richard Henderson.
>
> This has been tested on Loongson3A and Octeon CPUs by booting arm, i386,
> x86_64 and ppc guests.
>
> Aurelien Jarno (10):
> tcg-mips: fix wrong usage of 'Z' constraint
> tcg/mips: kill warnings in user mode
> tcg/mips: use TCGArg or TCGReg instead of int
> tcg/mips: don't use global pointer
> tcg/mips: use stack for TCG temps
> tcg/mips: optimize brcond arg, 0
> tcg/mips: optimize bswap{16,16s,32} on MIPS32R2
> tcg/mips: implement rotl/rotr ops on MIPS32R2
> tcg/mips: implement deposit op on MIPS32R2
> tcg/mips: implement movcond op on MIPS32R2
>
> tcg/mips/tcg-target.c | 336 +++++++++++++++++++++++++++++++++++--------------
> tcg/mips/tcg-target.h | 25 +++-
> 2 files changed, 266 insertions(+), 95 deletions(-)
>
While I didn't double-check the actual instruction encodings, I looked
through the patches for typos and logic errors. I didn't see anything
except for patch 4 re the handling of the global pointer. That patch
is fine as written, though I believe it could be improved.
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 18+ messages in thread