From: Leon Alrae <leon.alrae@imgtec.com>
To: James Hogan <james.hogan@imgtec.com>, qemu-devel@nongnu.org
Cc: aurelien@aurel32.net
Subject: Re: [Qemu-devel] [PATCH 4/7] target-mips: add MTHC0 and MFHC0 instructions
Date: Wed, 29 Apr 2015 15:26:53 +0100 [thread overview]
Message-ID: <5540EA2D.3010602@imgtec.com> (raw)
In-Reply-To: <553FACB3.2030603@imgtec.com>
On 28/04/2015 16:52, James Hogan wrote:
>> diff --git a/disas/mips.c b/disas/mips.c
>> index 1afe0c5..c236495 100644
>> --- a/disas/mips.c
>> +++ b/disas/mips.c
>> @@ -2238,6 +2238,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
>> {"ceil.l.s", "D,S", 0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3|I33 },
>> {"ceil.w.d", "D,S", 0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 },
>> {"ceil.w.s", "D,S", 0x4600000e, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 },
>> +{"mfhc0", "t,G,H", 0x40400000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I33 },
>> +{"mthc0", "t,G,H", 0x40c00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I33 },
>
> whitespace appears to be inconsistent here (the context uses tabs).
According to QEMU Coding Style we never use tabs, so we cannot avoid
this inconsistency unless we modify all entries in the table.
>
>> {"cfc0", "t,G", 0x40400000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 },
>> {"cfc1", "t,G", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 },
>> {"cfc1", "t,S", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 },
>> diff --git a/target-mips/translate.c b/target-mips/translate.c
>> index bb219ea..f95b655 100644
>> --- a/target-mips/translate.c
>> +++ b/target-mips/translate.c
>> @@ -868,8 +868,10 @@ enum {
>> enum {
>> OPC_MFC0 = (0x00 << 21) | OPC_CP0,
>> OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
>> + OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
>> OPC_MTC0 = (0x04 << 21) | OPC_CP0,
>> OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
>> + OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
>> OPC_MFTR = (0x08 << 21) | OPC_CP0,
>> OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
>> OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
>> @@ -1423,6 +1425,8 @@ typedef struct DisasContext {
>> int ie;
>> bool bi;
>> bool bp;
>> + uint64_t PAMask;
>> + bool mvh;
>> } DisasContext;
>>
>> enum {
>> @@ -1769,6 +1773,13 @@ static inline void check_cp1_registers(DisasContext *ctx, int regs)
>> This is enabled by CP0 Status register MX(24) bit.
>> */
>>
>> +static inline void check_mvh(DisasContext *ctx)
>> +{
>> + if (unlikely(!(ctx->mvh))) {
>
> superfluous brackets around ctx->mvh.
Will remove.
>
>> + generate_exception(ctx, EXCP_RI);
>> + }
>> +}
>> +
>> static inline void check_dsp(DisasContext *ctx)
>> {
>> if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
>> @@ -4820,6 +4831,60 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
>>
>> #ifndef CONFIG_USER_ONLY
>> /* CP0 (MMU and control) */
>> +static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
>> +{
>> + TCGv_i64 t0 = tcg_temp_new_i64();
>> + TCGv_i64 t1 = tcg_temp_new_i64();
>> +
>> + tcg_gen_ext_tl_i64(t0, arg);
>> + tcg_gen_ld_i64(t1, cpu_env, off);
>> +#if defined(TARGET_MIPS64)
>> + tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
>> +#else
>> + tcg_gen_concat32_i64(t1, t1, t0);
>
> I don't get what this case is about. what's wrong with the above case
> for MIPS64 and MIPS32?
As already clarified in the other email EntryLo.PFNX in MIPS32 starts at 32.
>
>> +#endif
>> + tcg_gen_st_i64(t1, cpu_env, off);
>> + tcg_temp_free_i64(t1);
>> + tcg_temp_free_i64(t0);
>> +}
>> +
>> +static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
>> +{
>> + TCGv_i64 t0 = tcg_temp_new_i64();
>> + TCGv_i64 t1 = tcg_temp_new_i64();
>> +
>> + tcg_gen_ext_tl_i64(t0, arg);
>> + tcg_gen_ld_i64(t1, cpu_env, off);
>> + tcg_gen_concat32_i64(t1, t1, t0);
>> + tcg_gen_st_i64(t1, cpu_env, off);
>> + tcg_temp_free_i64(t1);
>> + tcg_temp_free_i64(t0);
>
> simpler to just store a 32-bit value (st32_tl) to the appropriate half,
> depending on host endianness? (i.e. +4 if little endian)
Using the #ifdef HOST_WORDS_BIGENDIAN seems a bit ugly to me. I
personally prefer the current implementation.
>
>> +}
>> +
>> +static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
>> +{
>> + TCGv_i64 t0 = tcg_temp_new_i64();
>> +
>> + tcg_gen_ld_i64(t0, cpu_env, off);
>> +#if defined(TARGET_MIPS64)
>> + tcg_gen_shri_i64(t0, t0, 30);
>
> need to mask off the xi/ri bits?
Yeh, it was there before I did the last minute "improvements" (for some
reason I assumed that the trunc below would take care of it so masking
off was not required, but now I can see I was wrong). Thanks for
catching this.
>
>> +#else
>> + tcg_gen_shri_i64(t0, t0, 32);
>
> Again, I'm not convinced MIPS32 needs special handling here.
>
>> +#endif
>> + tcg_gen_trunc_i64_tl(arg, t0);
>> + tcg_temp_free_i64(t0);
>> +}
>> +
>> +static inline void gen_mfhc0_load64(TCGv arg, target_ulong off)
>> +{
>> + TCGv_i64 t0 = tcg_temp_new_i64();
>> +
>> + tcg_gen_ld_i64(t0, cpu_env, off);
>> + tcg_gen_shri_i64(t0, t0, 32);
>
> simpler to just load a signed 32-bit value (ld32s_tl) from the
> appropriate half, depending on host endianness? (i.e. +4 if little endian)
>
>> + tcg_gen_trunc_i64_tl(arg, t0);
>> + tcg_temp_free_i64(t0);
>> +}
>> +
>> static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
>> {
>> TCGv_i32 t0 = tcg_temp_new_i32();
>> @@ -4850,6 +4915,134 @@ static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
>> tcg_gen_st_tl(arg, cpu_env, off);
>> }
>>
>> +static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
>> +{
>> + const char *rn = "invalid";
>> +
>> + if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
>
> worth reusing the CP0_CHECK stuff?
Currently CP0_CHECK tests only for unimplemented registers which I think
doesn’t fit well here.
>
>> + goto mfhc0_read_zero;
>> + }
>> +
>> + switch (reg) {
>> + case 2:
>> + switch (sel) {
>> + case 0:
>> + gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
>> + rn = "EntryLo0";
>> + break;
>> + default:
>> + goto mfhc0_read_zero;
>> + }
>> + break;
>> + case 3:
>> + switch (sel) {
>> + case 0:
>> + gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
>> + rn = "EntryLo1";
>> + break;
>> + default:
>> + goto mfhc0_read_zero;
>> + }
>> + break;
>> + case 17:
>> + switch (sel) {
>> + case 0:
>> + gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr));
>> + rn = "LLAddr";
>> + break;
>> + default:
>> + goto mfhc0_read_zero;
>> + }
>> + break;
>> + case 28:
>> + switch (sel) {
>> + case 0:
>> + case 2:
>> + case 4:
>> + case 6:
>> + gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo));
>> + rn = "TagLo";
>> + break;
>> + default:
>> + goto mfhc0_read_zero;
>> + }
>> + break;
>> + default:
>> + goto mfhc0_read_zero;
>> + }
>> +
>> + (void)rn; /* avoid a compiler warning */
>> + LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
>> + return;
>> +
>> +mfhc0_read_zero:
>> + LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
>> + tcg_gen_movi_tl(arg, 0);
>> +}
>> +
>> +static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
>> +{
>> + const char *rn = "invalid";
>> +
>> + if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
>> + goto mthc0_nop;
>> + }
>> +
>> + tcg_gen_andi_tl(arg, arg, ctx->PAMask >> 36);
>
> Shouldn't this depend on the register? LLAddr shift varies per core
> (CP0_LLAddr_shift), but EntryLo shift will be the same for each core.
Yes, it should. I'll correct that.
Thanks,
Leon
next prev parent reply other threads:[~2015-04-29 14:27 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-28 12:41 [Qemu-devel] [PATCH 0/7] target-mips: add support for large physical addresses Leon Alrae
2015-04-28 12:41 ` [Qemu-devel] [PATCH 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32 Leon Alrae
2015-04-28 12:41 ` [Qemu-devel] [PATCH 2/7] target-mips: support Page Frame Number Extension field Leon Alrae
2015-04-28 13:35 ` James Hogan
2015-04-28 13:47 ` James Hogan
2015-04-28 15:59 ` Leon Alrae
2015-04-28 21:39 ` James Hogan
2015-04-29 15:31 ` Leon Alrae
2015-04-28 12:41 ` [Qemu-devel] [PATCH 3/7] target-mips: add CP0.PageGrain.ELPA support Leon Alrae
2015-04-28 15:08 ` James Hogan
2015-04-29 11:35 ` Leon Alrae
2015-04-28 12:41 ` [Qemu-devel] [PATCH 4/7] target-mips: add MTHC0 and MFHC0 instructions Leon Alrae
2015-04-28 15:52 ` James Hogan
2015-04-29 14:26 ` Leon Alrae [this message]
2015-04-28 12:41 ` [Qemu-devel] [PATCH 5/7] target-mips: correct MFC0 for CP0.EntryLo in MIPS64 Leon Alrae
2015-04-28 12:41 ` [Qemu-devel] [PATCH 6/7] target-mips: remove invalid comments in translate_init.c Leon Alrae
2015-04-28 21:50 ` James Hogan
2015-04-28 12:41 ` [Qemu-devel] [PATCH 7/7] target-mips: enable XPA and LPA features Leon Alrae
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5540EA2D.3010602@imgtec.com \
--to=leon.alrae@imgtec.com \
--cc=aurelien@aurel32.net \
--cc=james.hogan@imgtec.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.