* [Qemu-devel] [PATCH 1/5] tcg-sparc: Add tcg_out_arithc.
2010-01-11 19:22 [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Richard Henderson
@ 2010-01-11 17:51 ` Richard Henderson
2010-01-11 17:57 ` [Qemu-devel] [PATCH 2/5] tcg-sparc: Implement add2, sub2, mulu2 Richard Henderson
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2010-01-11 17:51 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
Add a function to handle the register-vs-immediate test for arithmetic.
Also, adjust the OP_32_64 macro so that it auto-indents properly.
Rename the gen_arith32 label to gen_arith, since it handles 64-bit
arithmetic as well.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/sparc/tcg-target.c | 86 ++++++++++++++++++++++++------------------------
1 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 8f094e5..067e26e 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -285,6 +285,13 @@ static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
INSN_IMM13(offset));
}
+static void tcg_out_arithc(TCGContext *s, int rd, int rs1,
+ int val2, int val2const, int op)
+{
+ tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
+ | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
+}
+
static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
{
tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
@@ -481,10 +488,7 @@ static const uint8_t tcg_cond_to_bcond[10] = {
static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const)
{
- if (c2const)
- tcg_out_arithi(s, TCG_REG_G0, c1, c2, ARITH_SUBCC);
- else
- tcg_out_arith(s, TCG_REG_G0, c1, c2, ARITH_SUBCC);
+ tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
}
static void tcg_out_brcond_i32(TCGContext *s, int cond,
@@ -1036,22 +1040,22 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
#if TCG_TARGET_REG_BITS == 64
#define OP_32_64(x) \
- glue(glue(case INDEX_op_, x), _i32:) \
- glue(glue(case INDEX_op_, x), _i64:)
+ glue(glue(case INDEX_op_, x), _i32): \
+ glue(glue(case INDEX_op_, x), _i64)
#else
#define OP_32_64(x) \
- glue(glue(case INDEX_op_, x), _i32:)
+ glue(glue(case INDEX_op_, x), _i32)
#endif
- OP_32_64(ld8u);
+ OP_32_64(ld8u):
tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
break;
- OP_32_64(ld8s);
+ OP_32_64(ld8s):
tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
break;
- OP_32_64(ld16u);
+ OP_32_64(ld16u):
tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
break;
- OP_32_64(ld16s);
+ OP_32_64(ld16s):
tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
break;
case INDEX_op_ld_i32:
@@ -1060,10 +1064,10 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
#endif
tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
break;
- OP_32_64(st8);
+ OP_32_64(st8):
tcg_out_ldst(s, args[0], args[1], args[2], STB);
break;
- OP_32_64(st16);
+ OP_32_64(st16):
tcg_out_ldst(s, args[0], args[1], args[2], STH);
break;
case INDEX_op_st_i32:
@@ -1072,50 +1076,50 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
#endif
tcg_out_ldst(s, args[0], args[1], args[2], STW);
break;
- OP_32_64(add);
+ OP_32_64(add):
c = ARITH_ADD;
- goto gen_arith32;
- OP_32_64(sub);
+ goto gen_arith;
+ OP_32_64(sub):
c = ARITH_SUB;
- goto gen_arith32;
- OP_32_64(and);
+ goto gen_arith;
+ OP_32_64(and):
c = ARITH_AND;
- goto gen_arith32;
- OP_32_64(or);
+ goto gen_arith;
+ OP_32_64(or):
c = ARITH_OR;
- goto gen_arith32;
- OP_32_64(xor);
+ goto gen_arith;
+ OP_32_64(xor):
c = ARITH_XOR;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_shl_i32:
c = SHIFT_SLL;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_shr_i32:
c = SHIFT_SRL;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_sar_i32:
c = SHIFT_SRA;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_mul_i32:
c = ARITH_UMUL;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_div2_i32:
#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
c = ARITH_SDIVX;
- goto gen_arith32;
+ goto gen_arith;
#else
tcg_out_sety(s, 0);
c = ARITH_SDIV;
- goto gen_arith32;
+ goto gen_arith;
#endif
case INDEX_op_divu2_i32:
#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
c = ARITH_UDIVX;
- goto gen_arith32;
+ goto gen_arith;
#else
tcg_out_sety(s, 0);
c = ARITH_UDIV;
- goto gen_arith32;
+ goto gen_arith;
#endif
case INDEX_op_brcond_i32:
@@ -1173,22 +1177,22 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
break;
case INDEX_op_shl_i64:
c = SHIFT_SLLX;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_shr_i64:
c = SHIFT_SRLX;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_sar_i64:
c = SHIFT_SRAX;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_mul_i64:
c = ARITH_MULX;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_div2_i64:
c = ARITH_SDIVX;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_divu2_i64:
c = ARITH_UDIVX;
- goto gen_arith32;
+ goto gen_arith;
case INDEX_op_brcond_i64:
tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
@@ -1202,12 +1206,8 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
break;
#endif
- gen_arith32:
- if (const_args[2]) {
- tcg_out_arithi(s, args[0], args[1], args[2], c);
- } else {
- tcg_out_arith(s, args[0], args[1], args[2], c);
- }
+ gen_arith:
+ tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
break;
default:
--
1.6.5.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 2/5] tcg-sparc: Implement add2, sub2, mulu2.
2010-01-11 19:22 [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Richard Henderson
2010-01-11 17:51 ` [Qemu-devel] [PATCH 1/5] tcg-sparc: Add tcg_out_arithc Richard Henderson
@ 2010-01-11 17:57 ` Richard Henderson
2010-01-11 19:00 ` [Qemu-devel] [PATCH 3/5] tcg-sparc: Do not remove %o[012] from 'r' constraint Richard Henderson
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2010-01-11 17:57 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
Add missing 32-bit double-word support opcodes.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/sparc/tcg-target.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 067e26e..6934580 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -215,6 +215,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define BA (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
#define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00))
+#define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
#define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01))
#define ARITH_OR (INSN_OP(2) | INSN_OP3(0x02))
#define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
@@ -238,6 +239,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
#define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
+#define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
#define WRY (INSN_OP(2) | INSN_OP3(0x30))
#define JMPL (INSN_OP(2) | INSN_OP3(0x38))
#define SAVE (INSN_OP(2) | INSN_OP3(0x3c))
@@ -410,6 +412,11 @@ static inline void tcg_out_sety(TCGContext *s, tcg_target_long val)
fprintf(stderr, "unimplemented sety %ld\n", (long)val);
}
+static inline void tcg_out_rdy(TCGContext *s, int rd)
+{
+ tcg_out32(s, RDY | INSN_RD(rd));
+}
+
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
{
if (val != 0) {
@@ -1132,6 +1139,23 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
args[2], const_args[2],
args[3], const_args[3], args[5]);
break;
+ case INDEX_op_add2_i32:
+ tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
+ ARITH_ADDCC);
+ tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
+ ARITH_ADDX);
+ break;
+ case INDEX_op_sub2_i32:
+ tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
+ ARITH_SUBCC);
+ tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
+ ARITH_SUBX);
+ break;
+ case INDEX_op_mulu2_i32:
+ tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
+ ARITH_UMUL);
+ tcg_out_rdy(s, args[1]);
+ break;
#endif
case INDEX_op_qemu_ld8u:
@@ -1250,6 +1274,9 @@ static const TCGTargetOpDef sparc_op_defs[] = {
{ INDEX_op_brcond_i32, { "r", "rJ" } },
#if TCG_TARGET_REG_BITS == 32
{ INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } },
+ { INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
+ { INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
+ { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
#endif
{ INDEX_op_qemu_ld8u, { "r", "L" } },
--
1.6.5.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 3/5] tcg-sparc: Do not remove %o[012] from 'r' constraint.
2010-01-11 19:22 [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Richard Henderson
2010-01-11 17:51 ` [Qemu-devel] [PATCH 1/5] tcg-sparc: Add tcg_out_arithc Richard Henderson
2010-01-11 17:57 ` [Qemu-devel] [PATCH 2/5] tcg-sparc: Implement add2, sub2, mulu2 Richard Henderson
@ 2010-01-11 19:00 ` Richard Henderson
2010-01-11 19:09 ` [Qemu-devel] [PATCH 4/5] tcg-sparc: Implement division properly Richard Henderson
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2010-01-11 19:00 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
Only 'L' constraint needs that.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/sparc/tcg-target.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 6934580..8675fce 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -143,6 +143,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
ct_str = *pct_str;
switch (ct_str[0]) {
case 'r':
+ ct->ct |= TCG_CT_REG;
+ tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
+ break;
case 'L': /* qemu_ld/st constraint */
ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
--
1.6.5.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 4/5] tcg-sparc: Implement division properly.
2010-01-11 19:22 [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Richard Henderson
` (2 preceding siblings ...)
2010-01-11 19:00 ` [Qemu-devel] [PATCH 3/5] tcg-sparc: Do not remove %o[012] from 'r' constraint Richard Henderson
@ 2010-01-11 19:09 ` Richard Henderson
2010-01-11 20:11 ` Richard Henderson
2010-01-11 19:21 ` [Qemu-devel] [PATCH 5/5] tcg-sparc: Implement ext32[su]_i64 Richard Henderson
` (2 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2010-01-11 19:09 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
The {div,divu}2 opcodes are intended for systems for which the
division instruction produces both quotient and remainder. Sparc
is not such a system. Indeed, the remainder must be computed as
quot = a / b
rem = a - (quot * b)
Split out a tcg_out_div32 function that properly initializes Y
with the extension of the input to 64-bits. Discard the code
that used the 64-bit DIVX on sparc9/sparcv8plus without extending
the inputs to 64-bits. Implement remainders in terms of division
followed by multiplication.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/sparc/tcg-target.c | 82 ++++++++++++++++++++++++++++++-----------------
tcg/sparc/tcg-target.h | 3 ++
2 files changed, 55 insertions(+), 30 deletions(-)
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 8675fce..1bef2fb 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -243,7 +243,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
#define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
-#define WRY (INSN_OP(2) | INSN_OP3(0x30))
+#define WRY (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
#define JMPL (INSN_OP(2) | INSN_OP3(0x38))
#define SAVE (INSN_OP(2) | INSN_OP3(0x3c))
#define RESTORE (INSN_OP(2) | INSN_OP3(0x3d))
@@ -407,12 +407,9 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
tcg_out_ldst(s, arg, arg1, arg2, STX);
}
-static inline void tcg_out_sety(TCGContext *s, tcg_target_long val)
+static inline void tcg_out_sety(TCGContext *s, int rs)
{
- if (val == 0 || val == -1)
- tcg_out32(s, WRY | INSN_IMM13(val));
- else
- fprintf(stderr, "unimplemented sety %ld\n", (long)val);
+ tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
}
static inline void tcg_out_rdy(TCGContext *s, int rd)
@@ -444,6 +441,21 @@ static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
}
}
+static void tcg_out_div32(TCGContext *s, int rd, int rs1,
+ int val2, int val2const, int uns)
+{
+ /* Load Y with the sign/zero extension of RS1 to 64-bits. */
+ if (uns) {
+ tcg_out_sety(s, TCG_REG_G0);
+ } else {
+ tcg_out_arith(s, TCG_REG_I5, rs1, 31, SHIFT_SRA);
+ tcg_out_sety(s, TCG_REG_I5);
+ }
+
+ tcg_out_arithc(s, rd, rs1, val2, val2const,
+ uns ? ARITH_UDIV : ARITH_SDIV);
+}
+
static inline void tcg_out_nop(TCGContext *s)
{
tcg_out_sethi(s, TCG_REG_G0, 0);
@@ -1113,24 +1125,22 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
case INDEX_op_mul_i32:
c = ARITH_UMUL;
goto gen_arith;
- case INDEX_op_div2_i32:
-#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
- c = ARITH_SDIVX;
- goto gen_arith;
-#else
- tcg_out_sety(s, 0);
- c = ARITH_SDIV;
- goto gen_arith;
-#endif
- case INDEX_op_divu2_i32:
-#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
- c = ARITH_UDIVX;
- goto gen_arith;
-#else
- tcg_out_sety(s, 0);
- c = ARITH_UDIV;
- goto gen_arith;
-#endif
+
+ case INDEX_op_div_i32:
+ tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 0);
+ break;
+ case INDEX_op_divu_i32:
+ tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
+ break;
+
+ case INDEX_op_rem_i32:
+ case INDEX_op_remu_i32:
+ tcg_out_div32(s, TCG_REG_I5, args[1], args[2], const_args[2],
+ opc == INDEX_op_remu_i32);
+ tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
+ ARITH_UMUL);
+ tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
+ break;
case INDEX_op_brcond_i32:
tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
@@ -1214,12 +1224,20 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
case INDEX_op_mul_i64:
c = ARITH_MULX;
goto gen_arith;
- case INDEX_op_div2_i64:
+ case INDEX_op_div_i64:
c = ARITH_SDIVX;
goto gen_arith;
- case INDEX_op_divu2_i64:
+ case INDEX_op_divu_i64:
c = ARITH_UDIVX;
goto gen_arith;
+ case INDEX_op_rem_i64:
+ case INDEX_op_remu_i64:
+ tcg_out_arithc(s, TCG_REG_I5, args[1], args[2], const_args[2],
+ opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
+ tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
+ ARITH_MULX);
+ tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
+ break;
case INDEX_op_brcond_i64:
tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
@@ -1263,8 +1281,10 @@ static const TCGTargetOpDef sparc_op_defs[] = {
{ INDEX_op_add_i32, { "r", "r", "rJ" } },
{ INDEX_op_mul_i32, { "r", "r", "rJ" } },
- { INDEX_op_div2_i32, { "r", "r", "0", "1", "r" } },
- { INDEX_op_divu2_i32, { "r", "r", "0", "1", "r" } },
+ { INDEX_op_div_i32, { "r", "r", "rJ" } },
+ { INDEX_op_divu_i32, { "r", "r", "rJ" } },
+ { INDEX_op_rem_i32, { "r", "r", "rJ" } },
+ { INDEX_op_remu_i32, { "r", "r", "rJ" } },
{ INDEX_op_sub_i32, { "r", "r", "rJ" } },
{ INDEX_op_and_i32, { "r", "r", "rJ" } },
{ INDEX_op_or_i32, { "r", "r", "rJ" } },
@@ -1312,8 +1332,10 @@ static const TCGTargetOpDef sparc_op_defs[] = {
{ INDEX_op_add_i64, { "r", "r", "rJ" } },
{ INDEX_op_mul_i64, { "r", "r", "rJ" } },
- { INDEX_op_div2_i64, { "r", "r", "0", "1", "r" } },
- { INDEX_op_divu2_i64, { "r", "r", "0", "1", "r" } },
+ { INDEX_op_div_i64, { "r", "r", "rJ" } },
+ { INDEX_op_divu_i64, { "r", "r", "rJ" } },
+ { INDEX_op_rem_i64, { "r", "r", "rJ" } },
+ { INDEX_op_remu_i64, { "r", "r", "rJ" } },
{ INDEX_op_sub_i64, { "r", "r", "rJ" } },
{ INDEX_op_and_i64, { "r", "r", "rJ" } },
{ INDEX_op_or_i64, { "r", "r", "rJ" } },
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index e8f8f65..e00707b 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -88,6 +88,9 @@ enum {
#endif
/* optional instructions */
+#define TCG_TARGET_HAS_div_i32
+#define TCG_TARGET_HAS_div_i64
+
//#define TCG_TARGET_HAS_bswap32_i32
//#define TCG_TARGET_HAS_bswap64_i64
//#define TCG_TARGET_HAS_neg_i32
--
1.6.5.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 5/5] tcg-sparc: Implement ext32[su]_i64
2010-01-11 19:22 [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Richard Henderson
` (3 preceding siblings ...)
2010-01-11 19:09 ` [Qemu-devel] [PATCH 4/5] tcg-sparc: Implement division properly Richard Henderson
@ 2010-01-11 19:21 ` Richard Henderson
2010-01-11 20:41 ` [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Palle Lyckegaard
2010-01-12 20:02 ` [Qemu-devel] " Blue Swirl
6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2010-01-11 19:21 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
The 32-bit right-shift instructions is defined to extend the shifted
output to 64-bits. A shift count of zero therefore is a simple
extension without actually shifting.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/sparc/tcg-target.c | 16 ++++++++++++++++
tcg/sparc/tcg-target.h | 5 +++++
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 1bef2fb..bc28f43 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1238,6 +1238,20 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
ARITH_MULX);
tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
break;
+ case INDEX_op_ext32s_i64:
+ if (const_args[1]) {
+ tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
+ } else {
+ tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
+ }
+ break;
+ case INDEX_op_ext32u_i64:
+ if (const_args[1]) {
+ tcg_out_movi_imm32(s, args[0], args[1]);
+ } else {
+ tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
+ }
+ break;
case INDEX_op_brcond_i64:
tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
@@ -1344,6 +1358,8 @@ static const TCGTargetOpDef sparc_op_defs[] = {
{ INDEX_op_shl_i64, { "r", "r", "rJ" } },
{ INDEX_op_shr_i64, { "r", "r", "rJ" } },
{ INDEX_op_sar_i64, { "r", "r", "rJ" } },
+ { INDEX_op_ext32s_i64, { "r", "ri" } },
+ { INDEX_op_ext32u_i64, { "r", "ri" } },
{ INDEX_op_brcond_i64, { "r", "rJ" } },
#endif
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index e00707b..d27ed5a 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -91,6 +91,11 @@ enum {
#define TCG_TARGET_HAS_div_i32
#define TCG_TARGET_HAS_div_i64
+#if TCG_TARGET_REG_BITS == 64
+#define TCG_TARGET_HAS_ext32s_i64
+#define TCG_TARGET_HAS_ext32u_i64
+#endif
+
//#define TCG_TARGET_HAS_bswap32_i32
//#define TCG_TARGET_HAS_bswap64_i64
//#define TCG_TARGET_HAS_neg_i32
--
1.6.5.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 0/5] tcg-sparc improvements
2010-01-11 19:22 [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Richard Henderson
` (4 preceding siblings ...)
2010-01-11 19:21 ` [Qemu-devel] [PATCH 5/5] tcg-sparc: Implement ext32[su]_i64 Richard Henderson
@ 2010-01-11 20:41 ` Palle Lyckegaard
2010-01-12 20:02 ` [Qemu-devel] " Blue Swirl
6 siblings, 0 replies; 9+ messages in thread
From: Palle Lyckegaard @ 2010-01-11 20:41 UTC (permalink / raw)
To: Richard Henderson; +Cc: blauwirbel, qemu-devel
On Mon, 11 Jan 2010, Richard Henderson wrote:
>
> Richard Henderson (5):
> tcg-sparc: Add tcg_out_arithc.
> tcg-sparc: Implement add2, sub2, mulu2.
> tcg-sparc: Do not remove %o[012] from 'r' constraint.
> tcg-sparc: Implement division properly.
> tcg-sparc: Implement ext32[su]_i64
>
Great work :-) Now the NetBSD malta kernel boots using qemu-system-mips on
a sparc target!
log:
uname -a
SunOS opensolaris 5.11 snv_111b sun4u sparc SUNW,Ultra-5_10 Solaris
./mips-softmmu/qemu-system-mips --kernel ../../netbsd_malta -m 64
-nographic
MIPS32/64 params: cpu arch: 32
MIPS32/64 params: TLB entries: 16
MIPS32/64 params: Icache: line = 16, total = 2048, ways = 2
sets = 64
MIPS32/64 params: Dcache: line = 16, total = 2048, ways = 2
sets = 64
picache_stride = 1024
picache_loopcount = 2
pdcache_stride = 1024
pdcache_loopcount = 2
[ Kernel symbol table missing! ]
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
NetBSD 5.0.1 (MALTA) #0: Wed Jul 29 19:36:39 UTC 2009
builds@b8.netbsd.org:/home/builds/ab/netbsd-5-0-1-RELEASE/evbmips-mipseb/200907292356Z-obj/home/builds/ab/netbsd-5-0-1-RELEASE/src/sys/arch/evbmips/compile/MALTA
total memory = 65536 KB
avail memory = 59460 KB
mainbus0 (root)
cpu0 at mainbus0: 2152.04MHz (hz cycles = 10760233, delay divisor = 1076)
cpu0: MIPS 24K (0x19300) Rev. 0 with software emulated floating point
cpu0: 2KB/16B 2-way set-associative L1 Instruction cache, 16 TLB entries
cpu0: 2KB/16B 2-way set-associative write-back L1 Data cache
gt0 at mainbus0 addr 0x1be00000
pci0 at gt0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH 0/5] tcg-sparc improvements
2010-01-11 19:22 [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Richard Henderson
` (5 preceding siblings ...)
2010-01-11 20:41 ` [Qemu-devel] [PATCH 0/5] tcg-sparc improvements Palle Lyckegaard
@ 2010-01-12 20:02 ` Blue Swirl
6 siblings, 0 replies; 9+ messages in thread
From: Blue Swirl @ 2010-01-12 20:02 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Mon, Jan 11, 2010 at 7:22 PM, Richard Henderson <rth@twiddle.net> wrote:
> As noticed elsewhere on the list mulu2_i32 is missing. Which led
> me to notice that add2_i32 and sub2_i32 were also missing and also
> led me to notice that division was incorrectly implemented.
>
> My initial implementation of 32-bit division copied the existing practice
> of using the 64-bit division insns for sparcv9, with proper sign/zero
> extensions on the input operands. But that required extra temporaries
> and quickly got ugly. In the end I thought it was clearer to simply use
> the 32-bit division insns unconditionally.
>
> That excercise, however, made me notice that 32-bit extension was not
> special-cased, leading to the final patch.
Thanks, applied all (4/5 with your fix).
^ permalink raw reply [flat|nested] 9+ messages in thread