[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 087/147] target-s390: Convert FLOGR
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 087/147] target-s390: Convert FLOGR |
Date: |
Thu, 27 Sep 2012 17:21:06 -0700 |
Signed-off-by: Richard Henderson <address@hidden>
---
target-s390x/cc_helper.c | 8 ++++++
target-s390x/cpu.h | 2 ++
target-s390x/helper.h | 2 +-
target-s390x/insn-data.def | 3 +++
target-s390x/int_helper.c | 22 +++-------------
target-s390x/translate.c | 66 +++++++++++++++++++++++++---------------------
6 files changed, 53 insertions(+), 50 deletions(-)
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
index 27aac03..46c6d84 100644
--- a/target-s390x/cc_helper.c
+++ b/target-s390x/cc_helper.c
@@ -399,6 +399,11 @@ static uint32_t cc_calc_sla_64(uint64_t src, int shift)
return 2;
}
+static uint32_t cc_calc_flogr(uint64_t dst)
+{
+ return dst ? 2 : 0;
+}
+
static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
uint64_t src, uint64_t dst, uint64_t vr)
{
@@ -504,6 +509,9 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t
cc_op,
case CC_OP_SLA_64:
r = cc_calc_sla_64(src, dst);
break;
+ case CC_OP_FLOGR:
+ r = cc_calc_flogr(dst);
+ break;
case CC_OP_NZ_F32:
r = set_cc_nz_f32(dst);
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 7d17bf3..a6a6e3f 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -478,6 +478,7 @@ enum cc_op {
CC_OP_ICM, /* insert characters under mask */
CC_OP_SLA_32, /* Calculate shift left signed (32bit) */
CC_OP_SLA_64, /* Calculate shift left signed (64bit) */
+ CC_OP_FLOGR, /* find leftmost one */
CC_OP_MAX
};
@@ -521,6 +522,7 @@ static const char *cc_names[] = {
[CC_OP_ICM] = "CC_OP_ICM",
[CC_OP_SLA_32] = "CC_OP_SLA_32",
[CC_OP_SLA_64] = "CC_OP_SLA_64",
+ [CC_OP_FLOGR] = "CC_OP_FLOGR",
};
static inline const char *cc_name(int cc_op)
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index 5d42951..be37f8a 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -69,7 +69,7 @@ DEF_HELPER_4(msdb, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_2(tceb, TCG_CALL_PURE | TCG_CALL_CONST, i32, i64, i64)
DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_PURE | TCG_CALL_CONST, i32, i64, i64)
DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE | TCG_CALL_CONST, i32, i64, i64, i64)
-DEF_HELPER_3(flogr, i32, env, i32, i64)
+DEF_HELPER_FLAGS_1(clz, TCG_CALL_PURE | TCG_CALL_CONST, i64, i64)
DEF_HELPER_2(sqeb, i64, env, i64)
DEF_HELPER_2(sqdb, i64, env, i64)
DEF_HELPER_3(sqxb, i64, env, i64, i64)
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index d5e1c5c..771baaf 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -220,6 +220,9 @@
/* EXTRACT FPC */
C(0xb38c, EFPC, RRE, Z, 0, 0, new, r1_32, efpc, 0)
+/* FIND LEFTMOST ONE */
+ C(0xb983, FLOGR, RRE, EI, 0, r2_o, r1_P, 0, flogr, 0)
+
/* INSERT CHARACTER */
C(0x4300, IC, RX_a, Z, 0, m2_8u, 0, r1_8, mov2, 0)
C(0xe373, ICY, RXY_a, LD, 0, m2_8u, 0, r1_8, mov2, 0)
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
index f2f420c..00f764c 100644
--- a/target-s390x/int_helper.c
+++ b/target-s390x/int_helper.c
@@ -165,26 +165,10 @@ int64_t HELPER(nabs_i64)(int64_t val)
}
}
-/* find leftmost one */
-uint32_t HELPER(flogr)(CPUS390XState *env, uint32_t r1, uint64_t v2)
+/* count leading zeros, for find leftmost one */
+uint64_t HELPER(clz)(uint64_t v)
{
- uint64_t res = 0;
- uint64_t ov2 = v2;
-
- while (!(v2 & 0x8000000000000000ULL) && v2) {
- v2 <<= 1;
- res++;
- }
-
- if (!v2) {
- env->regs[r1] = 64;
- env->regs[r1 + 1] = 0;
- return 0;
- } else {
- env->regs[r1] = res;
- env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
- return 2;
- }
+ return clz64(v);
}
uint64_t HELPER(cvd)(int32_t bin)
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 6694443..e65b752 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -620,6 +620,7 @@ static void gen_op_calc_cc(DisasContext *s)
case CC_OP_COMP_64:
case CC_OP_NZ_F32:
case CC_OP_NZ_F64:
+ case CC_OP_FLOGR:
/* 1 argument */
gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
break;
@@ -852,6 +853,20 @@ static void disas_jcc(DisasContext *s, DisasCompare *c,
uint32_t mask)
account_inline_branch(s, old_cc_op);
break;
+ case CC_OP_FLOGR:
+ switch (mask & 0xa) {
+ case 8: /* src == 0 -> no one bit found */
+ cond = TCG_COND_EQ;
+ break;
+ case 2: /* src != 0 -> one bit found */
+ cond = TCG_COND_NE;
+ break;
+ default:
+ goto do_dynamic;
+ }
+ account_inline_branch(s, old_cc_op);
+ break;
+
default:
do_dynamic:
/* Calculate cc value. */
@@ -888,6 +903,7 @@ static void disas_jcc(DisasContext *s, DisasCompare *c,
uint32_t mask)
case CC_OP_LTGT0_64:
case CC_OP_NZ:
+ case CC_OP_FLOGR:
c->u.s64.a = cc_dst;
c->u.s64.b = tcg_const_i64(0);
c->g1 = true;
@@ -1414,29 +1430,6 @@ static void disas_b3(CPUS390XState *env, DisasContext
*s, int op, int m3,
#undef FP_HELPER
}
-static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
- int r2)
-{
- TCGv_i64 tmp;
- TCGv_i32 tmp32_1;
-
- LOG_DISAS("disas_b9: op 0x%x r1 %d r2 %d\n", op, r1, r2);
- switch (op) {
- case 0x83: /* FLOGR R1,R2 [RRE] */
- tmp = load_reg(r2);
- tmp32_1 = tcg_const_i32(r1);
- gen_helper_flogr(cc_op, cpu_env, tmp32_1, tmp);
- set_cc_static(s);
- tcg_temp_free_i64(tmp);
- tcg_temp_free_i32(tmp32_1);
- break;
- default:
- LOG_DISAS("illegal b9 operation 0x%x\n", op);
- gen_illegal_opcode(s);
- break;
- }
-}
-
static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
{
unsigned char opc;
@@ -1460,13 +1453,6 @@ static void disas_s390_insn(CPUS390XState *env,
DisasContext *s)
r2 = insn & 0xf;
disas_b3(env, s, op, r3, r1, r2);
break;
- case 0xb9:
- insn = ld_code4(env, s->pc);
- r1 = (insn >> 4) & 0xf;
- r2 = insn & 0xf;
- op = (insn >> 16) & 0xff;
- disas_b9(env, s, op, r1, r2);
- break;
default:
qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%x\n", opc);
gen_illegal_opcode(s);
@@ -2330,6 +2316,26 @@ static ExitStatus op_ex(DisasContext *s, DisasOps *o)
return NO_EXIT;
}
+static ExitStatus op_flogr(DisasContext *s, DisasOps *o)
+{
+ /* We'll use the original input for cc computation, since we get to
+ compare that against 0, which ought to be better than comparing
+ the real output against 64. It also lets cc_dst be a convenient
+ temporary during our computation. */
+ gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2);
+
+ /* R1 = IN ? CLZ(IN) : 64. */
+ gen_helper_clz(o->out, o->in2);
+
+ /* R1+1 = IN & ~(found bit). Note that we may attempt to shift this
+ value by 64, which is undefined. But since the shift is 64 iff the
+ input is zero, we still get the correct result after and'ing. */
+ tcg_gen_movi_i64(o->out2, 0x8000000000000000ull);
+ tcg_gen_shr_i64(o->out2, o->out2, o->out);
+ tcg_gen_andc_i64(o->out2, cc_dst, o->out2);
+ return NO_EXIT;
+}
+
static ExitStatus op_icm(DisasContext *s, DisasOps *o)
{
int m3 = get_field(s->fields, m3);
--
1.7.11.4
- [Qemu-devel] [PATCH 077/147] target-s390: Convert FP SUBTRACT, (continued)
- [Qemu-devel] [PATCH 077/147] target-s390: Convert FP SUBTRACT, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 078/147] target-s390: Convert FP DIVIDE, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 079/147] target-s390: Convert FP MULTIPLY, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 080/147] target-s390: Convert MULTIPLY AND ADD, SUBTRACT, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 081/147] target-s390: Convert TEST DATA CLASS, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 082/147] target-s390: Convert FP LOAD COMPLIMENT, NEGATIVE, POSITIVE, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 083/147] target-s390: Convert FP SQUARE ROOT, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 084/147] target-s390: Convert LOAD ZERO, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 085/147] target-s390: Convert CONVERT TO FIXED, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 086/147] target-s390: Convert CONVERT FROM FIXED, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 087/147] target-s390: Convert FLOGR,
Richard Henderson <=
- [Qemu-devel] [PATCH 088/147] target-s390: Convert LFPC, SFPC, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 089/147] target-s390: Convert IPM, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 090/147] target-s390: Convert CKSM, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 091/147] target-s390: Convert EAR, SAR, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 092/147] target-s390: Convert MVPG, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 093/147] target-s390: Convert CLST, MVST, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 094/147] target-s390: Convert SRST, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 095/147] target-s390: Convert STIDP, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 096/147] target-s390: Convert SCK, Richard Henderson, 2012/09/27
- [Qemu-devel] [PATCH 097/147] target-s390: Convert STCK, Richard Henderson, 2012/09/27