diff options
author | Siarhei Volkau <lis8215@gmail.com> | 2023-06-08 13:41:57 +0300 |
---|---|---|
committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2023-07-10 23:33:38 +0200 |
commit | bf1df65f0ae9a13c8677b3e63d77f0bd6320846c (patch) | |
tree | 2ac4a36ef1877d0114f826b9bd28f8b4831d7de2 /target | |
parent | ff7936f0093fab939bf4a8bff316b2cbd7f9f35f (diff) | |
download | qemu-bf1df65f0ae9a13c8677b3e63d77f0bd6320846c.zip qemu-bf1df65f0ae9a13c8677b3e63d77f0bd6320846c.tar.gz qemu-bf1df65f0ae9a13c8677b3e63d77f0bd6320846c.tar.bz2 |
target/mips/mxu: Add Q8ADD instruction
This instruction is used to add/subtract quadruple
8-bit values to another quadruple in parallel.
Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
Message-Id: <20230608104222.1520143-9-lis8215@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/mips/tcg/mxu_translate.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c index f170195..034287e 100644 --- a/target/mips/tcg/mxu_translate.c +++ b/target/mips/tcg/mxu_translate.c @@ -402,6 +402,7 @@ enum { OPC_MXU_D16AVGR = 0x03, OPC_MXU_Q8AVG = 0x04, OPC_MXU_Q8AVGR = 0x05, + OPC_MXU_Q8ADD = 0x07, }; /* @@ -1674,6 +1675,79 @@ static void gen_mxu_q8avg(DisasContext *ctx, bool round45) /* + * MXU instruction category: Arithmetic + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Q8ADD + */ + +/* + * Q8ADD XRa, XRb, XRc, ptn2 + * Add/subtract quadruple of 8-bit packed in XRb + * to another one in XRc, put the result in XRa. + */ +static void gen_mxu_Q8ADD(DisasContext *ctx) +{ + uint32_t aptn2, pad, XRc, XRb, XRa; + + aptn2 = extract32(ctx->opcode, 24, 2); + pad = extract32(ctx->opcode, 21, 3); + XRc = extract32(ctx->opcode, 14, 4); + XRb = extract32(ctx->opcode, 10, 4); + XRa = extract32(ctx->opcode, 6, 4); + + if (unlikely(pad != 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa == 0)) { + /* destination is zero register -> do nothing */ + } else if (unlikely((XRb == 0) && (XRc == 0))) { + /* both operands zero registers -> just set destination to zero */ + tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0); + } else { + /* the most general case */ + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); + TCGv t3 = tcg_temp_new(); + TCGv t4 = tcg_temp_new(); + + gen_load_mxu_gpr(t3, XRb); + gen_load_mxu_gpr(t4, XRc); + + for (int i = 0; i < 4; i++) { + tcg_gen_andi_tl(t0, t3, 0xff); + tcg_gen_andi_tl(t1, t4, 0xff); + + if (i < 2) { + if (aptn2 & 0x01) { + tcg_gen_sub_tl(t0, t0, t1); + } else { + tcg_gen_add_tl(t0, t0, t1); + } + } else { + if (aptn2 & 0x02) { + tcg_gen_sub_tl(t0, t0, t1); + } else { + tcg_gen_add_tl(t0, t0, t1); + } + } + if (i < 3) { + tcg_gen_shri_tl(t3, t3, 8); + tcg_gen_shri_tl(t4, t4, 8); + } + if (i > 0) { + tcg_gen_deposit_tl(t2, t2, t0, 8 * i, 8); + } else { + tcg_gen_andi_tl(t0, t0, 0xff); + tcg_gen_mov_tl(t2, t0); + } + } + gen_store_mxu_gpr(t2, XRa); + } +} + + +/* * MXU instruction category: align * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -2002,6 +2076,9 @@ static void decode_opc_mxu__pool01(DisasContext *ctx) case OPC_MXU_Q8AVGR: gen_mxu_q8avg(ctx, true); break; + case OPC_MXU_Q8ADD: + gen_mxu_Q8ADD(ctx); + break; default: MIPS_INVAL("decode_opc_mxu"); gen_reserved_instruction(ctx); |