[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu,
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu |
Date: |
Wed, 2 Sep 2015 17:17:40 -0700 |
Signed-off-by: Richard Henderson <address@hidden>
---
target-openrisc/translate.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 106 insertions(+)
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 6b96c53..cd684c7 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -336,6 +336,54 @@ static void gen_divu(DisasContext *dc, TCGv dest, TCGv
srca, TCGv srcb)
gen_ove_cy(dc);
}
+static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+
+ tcg_gen_ext_tl_i64(t1, srca);
+ tcg_gen_ext_tl_i64(t2, srcb);
+ if (TARGET_LONG_BITS == 32) {
+ tcg_gen_mul_i64(cpu_mac, t1, t2);
+ } else {
+ TCGv_i64 high = tcg_temp_new_i64();
+
+ tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
+ tcg_gen_sari_i64(t1, cpu_mac, 63);
+ tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high);
+ tcg_temp_free_i64(high);
+ tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
+ tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
+
+ gen_ove_ov(dc);
+ }
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+}
+
+static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+
+ tcg_gen_extu_tl_i64(t1, srca);
+ tcg_gen_extu_tl_i64(t2, srcb);
+ if (TARGET_LONG_BITS == 32) {
+ tcg_gen_mul_i64(cpu_mac, t1, t2);
+ } else {
+ TCGv_i64 high = tcg_temp_new_i64();
+
+ tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
+ tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
+ tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
+ tcg_temp_free_i64(high);
+
+ gen_ove_cy(dc);
+ }
+ tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t2);
+}
+
static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
{
TCGv_i64 t1 = tcg_temp_new_i64();
@@ -362,6 +410,25 @@ static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
gen_ove_ov(dc);
}
+static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+
+ tcg_gen_extu_tl_i64(t1, srca);
+ tcg_gen_extu_tl_i64(t2, srcb);
+ tcg_gen_mul_i64(t1, t1, t2);
+ tcg_temp_free_i64(t2);
+
+ /* Note that overflow is only computed during addition stage. */
+ tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
+ tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
+ tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
+ tcg_temp_free_i64(t1);
+
+ gen_ove_cy(dc);
+}
+
static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
{
TCGv_i64 t1 = tcg_temp_new_i64();
@@ -388,6 +455,25 @@ static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
gen_ove_ov(dc);
}
+static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+
+ tcg_gen_extu_tl_i64(t1, srca);
+ tcg_gen_extu_tl_i64(t2, srcb);
+ tcg_gen_mul_i64(t1, t1, t2);
+
+ /* Note that overflow is only computed during subtraction stage. */
+ tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
+ tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
+ tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
+ tcg_temp_free_i64(t2);
+ tcg_temp_free_i64(t1);
+
+ gen_ove_cy(dc);
+}
+
static void dec_calc(DisasContext *dc, uint32_t insn)
{
uint32_t op0, op1, op2;
@@ -523,6 +609,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
+ case 0x7: /* l.muld */
+ LOG_DIS("l.muld r%d, r%d\n", ra, rb);
+ gen_muld(dc, cpu_R[ra], cpu_R[rb]);
+ break;
+
case 0x9: /* l.div */
LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
@@ -537,6 +628,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
return;
+
+ case 0xc: /* l.muldu */
+ LOG_DIS("l.muldu r%d, r%d\n", ra, rb);
+ gen_muldu(dc, cpu_R[ra], cpu_R[rb]);
+ return;
}
break;
}
@@ -807,6 +903,16 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
gen_msb(dc, cpu_R[ra], cpu_R[rb]);
break;
+ case 0x0003: /* l.macu */
+ LOG_DIS("l.macu r%d, r%d\n", ra, rb);
+ gen_macu(dc, cpu_R[ra], cpu_R[rb]);
+ break;
+
+ case 0x0004: /* l.msbu */
+ LOG_DIS("l.msbu r%d, r%d\n", ra, rb);
+ gen_msbu(dc, cpu_R[ra], cpu_R[rb]);
+ break;
+
default:
gen_illegal_exception(dc);
break;
--
2.4.3
- [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode, (continued)
[Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction, Richard Henderson, 2015/09/02
[Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd, Richard Henderson, 2015/09/02
[Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu,
Richard Henderson <=
[Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa, Richard Henderson, 2015/09/02
[Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception, Richard Henderson, 2015/09/02