Skip to content

Commit

Permalink
target/mips/mxu: Add S32ALN S32LUI insns
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
SiarheiVolkau authored and philmd committed Jul 10, 2023
1 parent 29059e7 commit 5925963
Showing 1 changed file with 121 additions and 1 deletion.
122 changes: 121 additions & 1 deletion target/mips/tcg/mxu_translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -3066,7 +3068,7 @@ static void gen_mxu_d32asum(DisasContext *ctx)
* MXU instruction category: Miscellaneous
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* S32EXTR
* S32EXTR S32LUI
* S32EXTRV
* Q16SAT
*/
Expand Down Expand Up @@ -3182,6 +3184,59 @@ static void gen_mxu_s32extrv(DisasContext *ctx)
gen_store_mxu_gpr(t0, XRa);
}

/*
* 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
Expand Down Expand Up @@ -3461,6 +3516,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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 5925963

Please sign in to comment.