diff options
author | Siarhei Volkau <lis8215@gmail.com> | 2023-06-08 13:42:12 +0300 |
---|---|---|
committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2023-07-10 23:33:38 +0200 |
commit | 5925963476d65ce1a74651bbf48865977ff0c1b0 (patch) | |
tree | 706e09fbcc0b6d97397499e8dc2eaa0436b7022d /target | |
parent | 29059e72b0ddf6cddc94cccd61e0ef30063ff5be (diff) |
target/mips/mxu: Add S32ALN S32LUI insns
These instructions are part of pool16, see the grand opcode organization
tree on top of the file.
Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
Message-Id: <20230608104222.1520143-24-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 | 122 |
1 files changed, 121 insertions, 1 deletions
diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c index 0704a8c7ff..4f07201fcc 100644 --- a/target/mips/tcg/mxu_translate.c +++ b/target/mips/tcg/mxu_translate.c @@ -492,7 +492,9 @@ enum { * MXU pool 16 */ enum { + OPC_MXU_S32ALN = 0x01, OPC_MXU_S32ALNI = 0x02, + OPC_MXU_S32LUI = 0x03, OPC_MXU_S32NOR = 0x04, OPC_MXU_S32AND = 0x05, OPC_MXU_S32OR = 0x06, @@ -3066,7 +3068,7 @@ static void gen_mxu_d32asum(DisasContext *ctx) * MXU instruction category: Miscellaneous * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * S32EXTR + * S32EXTR S32LUI * S32EXTRV * Q16SAT */ @@ -3183,6 +3185,59 @@ static void gen_mxu_s32extrv(DisasContext *ctx) } /* + * S32LUI XRa, S8, optn3 + * Permutate the immediate S8 value to form a word + * to update XRa. + */ +static void gen_mxu_s32lui(DisasContext *ctx) +{ + uint32_t XRa, s8, optn3, pad; + + XRa = extract32(ctx->opcode, 6, 4); + s8 = extract32(ctx->opcode, 10, 8); + pad = extract32(ctx->opcode, 21, 2); + optn3 = extract32(ctx->opcode, 23, 3); + + if (unlikely(pad != 0)) { + /* opcode padding incorrect -> do nothing */ + } else if (unlikely(XRa == 0)) { + /* destination is zero register -> do nothing */ + } else { + uint32_t s16; + TCGv t0 = tcg_temp_new(); + + switch (optn3) { + case 0: + tcg_gen_movi_tl(t0, s8); + break; + case 1: + tcg_gen_movi_tl(t0, s8 << 8); + break; + case 2: + tcg_gen_movi_tl(t0, s8 << 16); + break; + case 3: + tcg_gen_movi_tl(t0, s8 << 24); + break; + case 4: + tcg_gen_movi_tl(t0, (s8 << 16) | s8); + break; + case 5: + tcg_gen_movi_tl(t0, (s8 << 24) | (s8 << 8)); + break; + case 6: + s16 = (uint16_t)(int16_t)(int8_t)s8; + tcg_gen_movi_tl(t0, (s16 << 16) | s16); + break; + case 7: + tcg_gen_movi_tl(t0, (s8 << 24) | (s8 << 16) | (s8 << 8) | s8); + break; + } + gen_store_mxu_gpr(t0, XRa); + } +} + +/* * Q16SAT XRa, XRb, XRc * Packs four 16-bit signed integers in XRb and XRc to * four saturated unsigned 8-bit into XRa. @@ -3462,6 +3517,65 @@ static void gen_mxu_S32ALNI(DisasContext *ctx) } /* + * S32ALN XRc, XRb, XRa, rs + * Arrange bytes from XRb and XRc according to one of five sets of + * rules determined by rs[2:0], and place the result in XRa. + */ +static void gen_mxu_S32ALN(DisasContext *ctx) +{ + uint32_t rs, XRc, XRb, XRa; + + rs = extract32(ctx->opcode, 21, 5); + XRc = extract32(ctx->opcode, 14, 4); + XRb = extract32(ctx->opcode, 10, 4); + XRa = extract32(ctx->opcode, 6, 4); + + 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 all 0s */ + tcg_gen_movi_tl(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(); + TCGLabel *l_exit = gen_new_label(); + TCGLabel *l_b_only = gen_new_label(); + TCGLabel *l_c_only = gen_new_label(); + + gen_load_mxu_gpr(t0, XRb); + gen_load_mxu_gpr(t1, XRc); + gen_load_gpr(t2, rs); + tcg_gen_andi_tl(t2, t2, 0x07); + + /* do nothing for undefined cases */ + tcg_gen_brcondi_tl(TCG_COND_GE, t2, 5, l_exit); + + tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l_b_only); + tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 4, l_c_only); + + tcg_gen_shli_tl(t2, t2, 3); + tcg_gen_subfi_tl(t3, 32, t2); + + tcg_gen_shl_tl(t0, t0, t2); + tcg_gen_shr_tl(t1, t1, t3); + tcg_gen_or_tl(mxu_gpr[XRa - 1], t0, t1); + tcg_gen_br(l_exit); + + gen_set_label(l_b_only); + gen_store_mxu_gpr(t0, XRa); + tcg_gen_br(l_exit); + + gen_set_label(l_c_only); + gen_store_mxu_gpr(t1, XRa); + + gen_set_label(l_exit); + } +} + +/* * S32MADD XRa, XRd, rb, rc * 32 to 64 bit signed multiply with subsequent add * result stored in {XRa, XRd} pair, stain HI/LO. @@ -3889,9 +4003,15 @@ static void decode_opc_mxu__pool16(DisasContext *ctx) uint32_t opcode = extract32(ctx->opcode, 18, 3); switch (opcode) { + case OPC_MXU_S32ALN: + gen_mxu_S32ALN(ctx); + break; case OPC_MXU_S32ALNI: gen_mxu_S32ALNI(ctx); break; + case OPC_MXU_S32LUI: + gen_mxu_s32lui(ctx); + break; case OPC_MXU_S32NOR: gen_mxu_S32NOR(ctx); break; |