[Qemu-devel] [PATCH 3/7] tcg-hppa: Implement deposit operation.
Signed-off-by: Richard Henderson
---
tcg/hppa/tcg-target.c | 58 +++-
tcg/hppa/tcg-target.h |1 +
2 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 7f4653e..a572cbf 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -467,6 +467,22 @@ static inline void tcg_out_dep(TCGContext *s, int ret, int
arg,
| INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
}
+static inline void tcg_out_depi(TCGContext *s, int ret, int arg,
+unsigned ofs, unsigned len)
+{
+assert(ofs < 32 && len <= 32 - ofs);
+tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(arg)
+ | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
+}
+
+static inline void tcg_out_zdep(TCGContext *s, int ret, int arg,
+unsigned ofs, unsigned len)
+{
+assert(ofs < 32 && len <= 32 - ofs);
+tcg_out32(s, INSN_ZDEP | INSN_R2(ret) | INSN_R1(arg)
+ | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
+}
+
static inline void tcg_out_shd(TCGContext *s, int ret, int hi, int lo,
unsigned count)
{
@@ -499,8 +515,7 @@ static void tcg_out_ori(TCGContext *s, int ret, int arg,
tcg_target_ulong m)
assert(bs1 == 32 || (1ul << bs1) > m);
tcg_out_mov(s, TCG_TYPE_I32, ret, arg);
-tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1)
- | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0));
+tcg_out_depi(s, ret, -1, bs0, bs1 - bs0);
}
static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m)
@@ -529,8 +544,7 @@ static void tcg_out_andi(TCGContext *s, int ret, int arg,
tcg_target_ulong m)
tcg_out_extr(s, ret, arg, 0, ls0, 0);
} else {
tcg_out_mov(s, TCG_TYPE_I32, ret, arg);
-tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0)
- | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0));
+tcg_out_depi(s, ret, 0, ls0, ls1 - ls0);
}
}
@@ -547,8 +561,7 @@ static inline void tcg_out_ext16s(TCGContext *s, int ret,
int arg)
static void tcg_out_shli(TCGContext *s, int ret, int arg, int count)
{
count &= 31;
-tcg_out32(s, INSN_ZDEP | INSN_R2(ret) | INSN_R1(arg)
- | INSN_SHDEP_CP(31 - count) | INSN_DEP_LEN(32 - count));
+tcg_out_zdep(s, ret, arg, count, 32 - count);
}
static void tcg_out_shl(TCGContext *s, int ret, int arg, int creg)
@@ -1407,6 +1420,38 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc, const TCGArg *args,
}
break;
+case INDEX_op_deposit_i32:
+{
+unsigned ofs = args[3], len = args[4];
+int arg2 = args[2];
+int arg1 = args[1];
+int arg0 = args[0];
+
+if (const_args[1]) {
+if (const_args[2]) {
+tcg_out_movi(s, TCG_TYPE_I32, arg0,
+ (arg2 & ((1u << len) - 1)) << ofs);
+} else {
+tcg_out_zdep(s, arg0, arg2, ofs, len);
+}
+} else {
+if (const_args[2]) {
+tcg_out_mov(s, TCG_TYPE_I32, arg0, arg1);
+tcg_out_depi(s, arg0, arg2, ofs, len);
+} else {
+if (arg0 != arg1) {
+if (arg0 == arg2) {
+tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R20, arg2);
+arg2 = TCG_REG_R20;
+}
+tcg_out_mov(s, TCG_TYPE_I32, arg0, arg1);
+}
+tcg_out_dep(s, arg0, arg2, ofs, len);
+}
+}
+}
+break;
+
case INDEX_op_mul_i32:
tcg_out_xmpyu(s, args[0], TCG_REG_R0, args[1], args[2]);
break;
@@ -1534,6 +1579,7 @@ static const TCGTargetOpDef hppa_op_defs[] = {
{ INDEX_op_sar_i32, { "r", "r", "ri" } },
{ INDEX_op_rotl_i32, { "r", "r", "ri" } },
{ INDEX_op_rotr_i32, { "r", "r", "ri" } },
+{ INDEX_op_deposit_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_bswap16_i32, { "r", "r" } },
{ INDEX_op_bswap32_i32, { "r", "r" } },
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index a5cc440..d3fe075 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -87,6 +87,7 @@ enum {
/* optional instructions */
// #define TCG_TARGET_HAS_div_i32
#define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_deposit_i32
#define TCG_TARGET_HAS_ext8s_i32
#define TCG_TARGET_HAS_ext16s_i32
#define TCG_TARGET_HAS_bswap16_i32
--
1.7.2.3
Re: [Qemu-devel] [PATCH 3/7] tcg-hppa: Implement deposit operation.
On 01/07/2011 03:35 PM, Stuart Brady wrote:
>> +static inline void tcg_out_depi(TCGContext *s, int ret, int arg,
>^^^
>> +unsigned ofs, unsigned len)
>> +{
>> +assert(ofs < 32 && len <= 32 - ofs);
>> +tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(val)
> ^^^
>
> The parameter should be named val, too.
Oops. It seems I failed to push that trivial change back from the gcc farm
test box.
>> +if (const_args[1]) {
>
> Surely const_args[1] && arg1 == 0?
This is implied by the "Z" constraint used.
r~
Re: [Qemu-devel] [PATCH 3/7] tcg-hppa: Implement deposit operation.
On Fri, Jan 07, 2011 at 02:42:59PM -0800, Richard Henderson wrote:
> Signed-off-by: Richard Henderson
> ---
> tcg/hppa/tcg-target.c | 58 +++-
> tcg/hppa/tcg-target.h |1 +
> 2 files changed, 53 insertions(+), 6 deletions(-)
>
> diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
> index 7f4653e..2c5df57 100644
> --- a/tcg/hppa/tcg-target.c
> +++ b/tcg/hppa/tcg-target.c
> @@ -467,6 +467,22 @@ static inline void tcg_out_dep(TCGContext *s, int ret,
> int arg,
>| INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
> }
>
> +static inline void tcg_out_depi(TCGContext *s, int ret, int arg,
^^^
> +unsigned ofs, unsigned len)
> +{
> +assert(ofs < 32 && len <= 32 - ofs);
> +tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(val)
^^^
The parameter should be named val, too.
[...]
> static void tcg_out_shl(TCGContext *s, int ret, int arg, int creg)
> @@ -1407,6 +1420,38 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
> opc, const TCGArg *args,
> }
> break;
>
> +case INDEX_op_deposit_i32:
> +{
> +unsigned ofs = args[3] >> 8, len = args[3] & 0xff;
> +int arg2 = args[2];
> +int arg1 = args[1];
> +int arg0 = args[0];
> +
> +if (const_args[1]) {
Surely const_args[1] && arg1 == 0?
> +if (const_args[2]) {
> +tcg_out_movi(s, TCG_TYPE_I32, arg0,
> + (arg2 & ((1u << len) - 1)) << ofs);
> +} else {
> +tcg_out_zdep(s, arg0, arg2, ofs, len);
> +}
Otherwise, looks good at first glance.
It'll be a few days before I can test on an HPPA box, though.
Cheers,
--
Stuart Brady
[Qemu-devel] [PATCH 3/7] tcg-hppa: Implement deposit operation.
Signed-off-by: Richard Henderson
---
tcg/hppa/tcg-target.c | 58 +++-
tcg/hppa/tcg-target.h |1 +
2 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 7f4653e..2c5df57 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -467,6 +467,22 @@ static inline void tcg_out_dep(TCGContext *s, int ret, int
arg,
| INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
}
+static inline void tcg_out_depi(TCGContext *s, int ret, int arg,
+unsigned ofs, unsigned len)
+{
+assert(ofs < 32 && len <= 32 - ofs);
+tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(val)
+ | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
+}
+
+static inline void tcg_out_zdep(TCGContext *s, int ret, int arg,
+unsigned ofs, unsigned len)
+{
+assert(ofs < 32 && len <= 32 - ofs);
+tcg_out32(s, INSN_ZDEP | INSN_R2(ret) | INSN_R1(arg)
+ | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
+}
+
static inline void tcg_out_shd(TCGContext *s, int ret, int hi, int lo,
unsigned count)
{
@@ -499,8 +515,7 @@ static void tcg_out_ori(TCGContext *s, int ret, int arg,
tcg_target_ulong m)
assert(bs1 == 32 || (1ul << bs1) > m);
tcg_out_mov(s, TCG_TYPE_I32, ret, arg);
-tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1)
- | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0));
+tcg_out_depi(ret, -1, bs0, bs1 - bs0);
}
static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m)
@@ -529,8 +544,7 @@ static void tcg_out_andi(TCGContext *s, int ret, int arg,
tcg_target_ulong m)
tcg_out_extr(s, ret, arg, 0, ls0, 0);
} else {
tcg_out_mov(s, TCG_TYPE_I32, ret, arg);
-tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0)
- | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0));
+tcg_out_depi(s, ret, 0, ls0, ls1 - ls0);
}
}
@@ -547,8 +561,7 @@ static inline void tcg_out_ext16s(TCGContext *s, int ret,
int arg)
static void tcg_out_shli(TCGContext *s, int ret, int arg, int count)
{
count &= 31;
-tcg_out32(s, INSN_ZDEP | INSN_R2(ret) | INSN_R1(arg)
- | INSN_SHDEP_CP(31 - count) | INSN_DEP_LEN(32 - count));
+tcg_out_zdep(s, ret, arg, count, 32 - count);
}
static void tcg_out_shl(TCGContext *s, int ret, int arg, int creg)
@@ -1407,6 +1420,38 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc, const TCGArg *args,
}
break;
+case INDEX_op_deposit_i32:
+{
+unsigned ofs = args[3] >> 8, len = args[3] & 0xff;
+int arg2 = args[2];
+int arg1 = args[1];
+int arg0 = args[0];
+
+if (const_args[1]) {
+if (const_args[2]) {
+tcg_out_movi(s, TCG_TYPE_I32, arg0,
+ (arg2 & ((1u << len) - 1)) << ofs);
+} else {
+tcg_out_zdep(s, arg0, arg2, ofs, len);
+}
+} else {
+if (const_args[2]) {
+tcg_out_mov(s, TCG_TYPE_I32, arg0, arg1);
+tcg_out_depi(s, arg0, arg2, ofs, len);
+} else {
+if (arg0 != arg1) {
+if (arg0 == arg2) {
+tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R20, arg2);
+arg2 = TCG_REG_R20;
+}
+tcg_out_mov(s, TCG_TYPE_I32, arg0, arg1);
+}
+tcg_out_dep(s, arg0, arg2, ofs, len);
+}
+}
+}
+break;
+
case INDEX_op_mul_i32:
tcg_out_xmpyu(s, args[0], TCG_REG_R0, args[1], args[2]);
break;
@@ -1534,6 +1579,7 @@ static const TCGTargetOpDef hppa_op_defs[] = {
{ INDEX_op_sar_i32, { "r", "r", "ri" } },
{ INDEX_op_rotl_i32, { "r", "r", "ri" } },
{ INDEX_op_rotr_i32, { "r", "r", "ri" } },
+{ INDEX_op_deposit_i32 { "r", "rZ", "rJ" } },
{ INDEX_op_bswap16_i32, { "r", "r" } },
{ INDEX_op_bswap32_i32, { "r", "r" } },
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index a5cc440..d3fe075 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -87,6 +87,7 @@ enum {
/* optional instructions */
// #define TCG_TARGET_HAS_div_i32
#define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_deposit_i32
#define TCG_TARGET_HAS_ext8s_i32
#define TCG_TARGET_HAS_ext16s_i32
#define TCG_TARGET_HAS_bswap16_i32
--
1.7.2.3
