MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of
the generic gen_HILO.
Signed-off-by: Fredrik Noring <noring@nocrew.org>
---
target/mips/translate.c | 67 ++++++++++++++++++++++++++++++++++-------
1 file changed, 56 insertions(+), 11 deletions(-)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 60320cbe69..f3993cf7d7 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -4359,24 +4359,72 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
tcg_temp_free(t1);
}
+/* Move to and from TX79 HI1/LO1 registers. */
+static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
+{
+ if (reg == 0 && (opc == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) {
+ /* Treat as NOP. */
+ return;
+ }
+
+ switch (opc) {
+ case TX79_MMI_MFHI1:
+#if defined(TARGET_MIPS64)
+ tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
+#else
+ tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
+#endif
+ break;
+ case TX79_MMI_MFLO1:
+#if defined(TARGET_MIPS64)
+ tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[1]);
+#else
+ tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
+#endif
+ break;
+ case TX79_MMI_MTHI1:
+ if (reg != 0) {
+#if defined(TARGET_MIPS64)
+ tcg_gen_ext32s_tl(cpu_HI[1], cpu_gpr[reg]);
+#else
+ tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
+#endif
+ } else {
+ tcg_gen_movi_tl(cpu_HI[1], 0);
+ }
+ break;
+ case TX79_MMI_MTLO1:
+ if (reg != 0) {
+#if defined(TARGET_MIPS64)
+ tcg_gen_ext32s_tl(cpu_LO[1], cpu_gpr[reg]);
+#else
+ tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
+#endif
+ } else {
+ tcg_gen_movi_tl(cpu_LO[1], 0);
+ }
+ break;
+ default:
+ MIPS_INVAL("MFTHILO TX79");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
/* Arithmetic on HI/LO registers */
static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
{
- if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
- opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
+ if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
/* Treat as NOP. */
return;
}
if (acc != 0) {
- if (!(ctx->insn_flags & INSN_R5900)) {
- check_dsp(ctx);
- }
+ check_dsp(ctx);
}
switch (opc) {
case OPC_MFHI:
- case TX79_MMI_MFHI1:
#if defined(TARGET_MIPS64)
if (acc != 0) {
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
@@ -4387,7 +4435,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
}
break;
case OPC_MFLO:
- case TX79_MMI_MFLO1:
#if defined(TARGET_MIPS64)
if (acc != 0) {
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
@@ -4398,7 +4445,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
}
break;
case OPC_MTHI:
- case TX79_MMI_MTHI1:
if (reg != 0) {
#if defined(TARGET_MIPS64)
if (acc != 0) {
@@ -4413,7 +4459,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
}
break;
case OPC_MTLO:
- case TX79_MMI_MTLO1:
if (reg != 0) {
#if defined(TARGET_MIPS64)
if (acc != 0) {
@@ -26500,11 +26545,11 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
break;
case TX79_MMI_MTLO1:
case TX79_MMI_MTHI1:
- gen_HILO(ctx, opc, 1, rs);
+ gen_HILO1_tx79(ctx, opc, rs);
break;
case TX79_MMI_MFLO1:
case TX79_MMI_MFHI1:
- gen_HILO(ctx, opc, 1, rd);
+ gen_HILO1_tx79(ctx, opc, rd);
break;
case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
--
2.18.1
On 2/11/18 17:08, Fredrik Noring wrote:
> MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of
> the generic gen_HILO.
>
Aleksandar, if you are OK with this patch, can you add:
Fixes: 8d927f7cb4b
> Signed-off-by: Fredrik Noring <noring@nocrew.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> target/mips/translate.c | 67 ++++++++++++++++++++++++++++++++++-------
> 1 file changed, 56 insertions(+), 11 deletions(-)
>
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 60320cbe69..f3993cf7d7 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -4359,24 +4359,72 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
> tcg_temp_free(t1);
> }
>
> +/* Move to and from TX79 HI1/LO1 registers. */
> +static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
> +{
> + if (reg == 0 && (opc == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) {
> + /* Treat as NOP. */
> + return;
> + }
> +
> + switch (opc) {
> + case TX79_MMI_MFHI1:
> +#if defined(TARGET_MIPS64)
> + tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
> +#else
> + tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
> +#endif
> + break;
> + case TX79_MMI_MFLO1:
> +#if defined(TARGET_MIPS64)
> + tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[1]);
> +#else
> + tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
> +#endif
> + break;
> + case TX79_MMI_MTHI1:
> + if (reg != 0) {
> +#if defined(TARGET_MIPS64)
> + tcg_gen_ext32s_tl(cpu_HI[1], cpu_gpr[reg]);
> +#else
> + tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
> +#endif
> + } else {
> + tcg_gen_movi_tl(cpu_HI[1], 0);
> + }
> + break;
> + case TX79_MMI_MTLO1:
> + if (reg != 0) {
> +#if defined(TARGET_MIPS64)
> + tcg_gen_ext32s_tl(cpu_LO[1], cpu_gpr[reg]);
> +#else
> + tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
> +#endif
> + } else {
> + tcg_gen_movi_tl(cpu_LO[1], 0);
> + }
> + break;
> + default:
> + MIPS_INVAL("MFTHILO TX79");
> + generate_exception_end(ctx, EXCP_RI);
> + break;
> + }
> +}
> +
> /* Arithmetic on HI/LO registers */
> static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
> {
> - if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
> - opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
> + if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
> /* Treat as NOP. */
> return;
> }
>
> if (acc != 0) {
> - if (!(ctx->insn_flags & INSN_R5900)) {
> - check_dsp(ctx);
> - }
> + check_dsp(ctx);
> }
>
> switch (opc) {
> case OPC_MFHI:
> - case TX79_MMI_MFHI1:
> #if defined(TARGET_MIPS64)
> if (acc != 0) {
> tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
> @@ -4387,7 +4435,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
> }
> break;
> case OPC_MFLO:
> - case TX79_MMI_MFLO1:
> #if defined(TARGET_MIPS64)
> if (acc != 0) {
> tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
> @@ -4398,7 +4445,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
> }
> break;
> case OPC_MTHI:
> - case TX79_MMI_MTHI1:
> if (reg != 0) {
> #if defined(TARGET_MIPS64)
> if (acc != 0) {
> @@ -4413,7 +4459,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
> }
> break;
> case OPC_MTLO:
> - case TX79_MMI_MTLO1:
> if (reg != 0) {
> #if defined(TARGET_MIPS64)
> if (acc != 0) {
> @@ -26500,11 +26545,11 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
> break;
> case TX79_MMI_MTLO1:
> case TX79_MMI_MTHI1:
> - gen_HILO(ctx, opc, 1, rs);
> + gen_HILO1_tx79(ctx, opc, rs);
> break;
> case TX79_MMI_MFLO1:
> case TX79_MMI_MFHI1:
> - gen_HILO(ctx, opc, 1, rd);
> + gen_HILO1_tx79(ctx, opc, rd);
> break;
> case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
> case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
>
On 11/2/18 4:08 PM, Fredrik Noring wrote:
> + switch (opc) {
> + case TX79_MMI_MFHI1:
> +#if defined(TARGET_MIPS64)
> + tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
> +#else
> + tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
> +#endif
You do not need this ifdef. This is already done in tcg/tcg-op.h:
$ grep tcg_gen_ext32s_tl tcg/tcg-op.h
#define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
#define tcg_gen_ext32s_tl tcg_gen_mov_i32
r~
Thank you for your reviews, Philippe and Richard,
> > + switch (opc) {
> > + case TX79_MMI_MFHI1:
> > +#if defined(TARGET_MIPS64)
> > + tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
> > +#else
> > + tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
> > +#endif
>
> You do not need this ifdef. This is already done in tcg/tcg-op.h:
>
> $ grep tcg_gen_ext32s_tl tcg/tcg-op.h
> #define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
> #define tcg_gen_ext32s_tl tcg_gen_mov_i32
It appears the correct function is tcg_gen_mov_tl because the TX79 manual
says
MFHI: GPR[rd]63..0 <- HI63..0
MFLO: GPR[rd]63..0 <- LO63..0
MTHI: HI63..0 <- GPR[rs]63..0
MTLO: LO63..0 <- GPR[rs]63..0
MFHI1: GPR[rd]63..0 <- HI127..64
MFLO1: GPR[rd]63..0 <- LO127..64
MTHI1: HI127..64 <- GPR[rs]63..0
MTLO1: LO127..64 <- GPR[rs]63..0
so the GPR is copied to/from in full in all cases. This is slightly
different to how acc = 1 is handled in gen_HILO.
Fredrik
On Sun, 4 Nov 2018, Fredrik Noring wrote: > It appears the correct function is tcg_gen_mov_tl because the TX79 manual > says > > MFHI: GPR[rd]63..0 <- HI63..0 > MFLO: GPR[rd]63..0 <- LO63..0 > MTHI: HI63..0 <- GPR[rs]63..0 > MTLO: LO63..0 <- GPR[rs]63..0 > MFHI1: GPR[rd]63..0 <- HI127..64 > MFLO1: GPR[rd]63..0 <- LO127..64 > MTHI1: HI127..64 <- GPR[rs]63..0 > MTLO1: LO127..64 <- GPR[rs]63..0 > > so the GPR is copied to/from in full in all cases. This is slightly > different to how acc = 1 is handled in gen_HILO. However `gen_HILO' looks wrong to me as it'll truncate the values of $acc3-$acc1 with the 64-bit DSP ASE. Maciej
Thanks for checking this, Maciej, [ Cc-ing Jia Liu, who added MIPS ASE DSP support in commit 4133498f8e532f "Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number", in case there are known ISA deviations. ] > However `gen_HILO' looks wrong to me as it'll truncate the values of > $acc3-$acc1 with the 64-bit DSP ASE. I can post a patch to fix gen_HILO. The best reference I have found so far is "MIPS Architecture for Programmers Volume IV-e: MIPS DSP Module for microMIPS64 Architecture" https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00765-2B-microMIPS64DSP-AFP-03.02.pdf that says MFHI: GPR[rds]63..0 <- HI[ac]63..0 MFLO: GPR[rdt]63..0 <- LO[ac]63..0 MTHI: HI[ac]63..0 <- GPR[rs]63..0 MTLO: LO[ac]63..0 <- GPR[rs]63..0 where ac can range from 0 to 3. Do you have a link to a better reference, by chance, that isn't tied to microMIPS? Fredrik
On Mon, 5 Nov 2018, Fredrik Noring wrote: > where ac can range from 0 to 3. Do you have a link to a better reference, > by chance, that isn't tied to microMIPS? Here: <https://www.mips.com/downloads/> you'll find everything you need I believe. HTH, Maciej
© 2016 - 2025 Red Hat, Inc.