aboutsummaryrefslogtreecommitdiff
path: root/target/mips/tcg
diff options
context:
space:
mode:
authorSiarhei Volkau <lis8215@gmail.com>2023-06-08 13:42:06 +0300
committerPhilippe Mathieu-Daudé <philmd@linaro.org>2023-07-10 23:33:38 +0200
commit513cfdae7a45a705f2fb2919ad95c82f66169c6e (patch)
tree388948fde3a3f34e519a57e454ed10e2fac3c26d /target/mips/tcg
parent98db7a585eb402579d2e5a7ec2b04fa22d12490a (diff)
downloadqemu-513cfdae7a45a705f2fb2919ad95c82f66169c6e.zip
qemu-513cfdae7a45a705f2fb2919ad95c82f66169c6e.tar.gz
qemu-513cfdae7a45a705f2fb2919ad95c82f66169c6e.tar.bz2
target/mips/mxu: Add D32ADDC instruction
The instruction adds two 32-bit values with respect to corresponding carry flags in MXU_CR. XRa += XRb + LeftCarry flag; XRd += XRc + RightCarry flag; Suddenly, it doesn't modify carry flags as a result of addition. Signed-off-by: Siarhei Volkau <lis8215@gmail.com> Message-Id: <20230608104222.1520143-18-lis8215@gmail.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'target/mips/tcg')
-rw-r--r--target/mips/tcg/mxu_translate.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index 82a0704..84e8f76 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -268,7 +268,7 @@
* │ 13..10
* ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
* │ └─ 0001 ─ OPC_MXU_S32SDIVR
- * ├─ 011000 ─ OPC_MXU_D32ADD
+ * ├─ 011000 ─ OPC_MXU_D32ADD (catches D32ADDC too)
* │ 23..22
* MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
* opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
@@ -2260,14 +2260,17 @@ static void gen_mxu_q16add(DisasContext *ctx)
/*
* D32ADD XRa, XRb, XRc, XRd, aptn2 - Double
- * 32 bit pattern addition/subtraction.
+ * 32 bit pattern addition/subtraction, set carry.
+ *
+ * D32ADDC XRa, XRb, XRc, XRd, aptn2 - Double
+ * 32 bit pattern addition/subtraction with carry.
*/
static void gen_mxu_d32add(DisasContext *ctx)
{
- uint32_t aptn2, pad, XRc, XRb, XRa, XRd;
+ uint32_t aptn2, addc, XRc, XRb, XRa, XRd;
aptn2 = extract32(ctx->opcode, 24, 2);
- pad = extract32(ctx->opcode, 22, 2);
+ addc = extract32(ctx->opcode, 22, 2);
XRd = extract32(ctx->opcode, 18, 4);
XRc = extract32(ctx->opcode, 14, 4);
XRb = extract32(ctx->opcode, 10, 4);
@@ -2276,15 +2279,37 @@ static void gen_mxu_d32add(DisasContext *ctx)
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
- TCGv carry = tcg_temp_new();
TCGv cr = tcg_temp_new();
- if (unlikely(pad != 0)) {
- /* opcode padding incorrect -> do nothing */
+ if (unlikely(addc > 1)) {
+ /* opcode incorrect -> do nothing */
+ } else if (addc == 1) {
+ if (unlikely(XRa == 0 && XRd == 0)) {
+ /* destinations are zero register -> do nothing */
+ } else {
+ /* FIXME ??? What if XRa == XRd ??? */
+ /* aptn2 is unused here */
+ gen_load_mxu_gpr(t0, XRb);
+ gen_load_mxu_gpr(t1, XRc);
+ gen_load_mxu_cr(cr);
+ if (XRa != 0) {
+ tcg_gen_extract_tl(t2, cr, 31, 1);
+ tcg_gen_add_tl(t0, t0, t2);
+ tcg_gen_add_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+ }
+ if (XRd != 0) {
+ tcg_gen_extract_tl(t2, cr, 30, 1);
+ tcg_gen_add_tl(t1, t1, t2);
+ tcg_gen_add_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t1);
+ }
+ }
} else if (unlikely(XRa == 0 && XRd == 0)) {
/* destinations are zero register -> do nothing */
} else {
/* common case */
+ /* FIXME ??? What if XRa == XRd ??? */
+ TCGv carry = tcg_temp_new();
+
gen_load_mxu_gpr(t0, XRb);
gen_load_mxu_gpr(t1, XRc);
gen_load_mxu_cr(cr);