[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset()
From: |
Richard Henderson |
Subject: |
Re: [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function |
Date: |
Wed, 18 Aug 2021 12:29:08 -1000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 |
On 8/18/21 11:31 AM, Philippe Mathieu-Daudé wrote:
I think you should drop
get_offset() entirely and replace it with
int dir = cpu_is_bigendian(env) ? 1 : -1;
stb(env, arg2 + 1 * dir, data);
stb(env, arg2 + 2 * dir, data);
Alternately, bite the bullet and split the function(s) into two,
explicitly endian versions: helper_swl_be, helper_swl_le, etc.
I'll go for the easier path ;)
It's not really more difficult.
static inline void do_swl(env, uint32_t val, target_ulong addr, int midx,
int dir, unsigned lmask, uintptr_t ra)
{
cpu_stb_mmuidx_ra(env, addr, val >> 24, midx, ra);
if (lmask <= 2) {
cpu_stb_mmuidx_ra(env, addr + 1 * dir, val >> 16, midx, ra);
}
if (lmask <= 1) {
cpu_stb_mmuidx_ra(env, addr + 1 * dir, val >> 8, midx, ra);
}
if (lmask == 0) {
cpu_stb_mmuidx_ra(env, addr + 1 * dir, val, midx, ra);
}
}
void helper_swl_be(env, val, addr, midx)
{
do_swl(env, val, addr, midx, 1, addr & 3, GETPC());
}
void helper_swl_le(env, val, addr, midx)
{
do_swl(env, val, addr, midx, -1, ~addr & 3, GETPC());
}
Although I do wonder if this is strictly correct with respect to atomicity. In my
tcg/mips unaligned patch set, I assumed that lwl+lwr of an aligned address produces two
atomic 32-bit loads, which result in a complete atomic load at the end.
Should we be doing something like
void helper_swl_be(env, val, addr, midx)
{
uintptr_t ra = GETPC();
switch (addr & 3) {
case 0:
cpu_stl_be_mmuidx_ra(env, val, addr, midx, ra);
break;
case 1:
cpu_stb_mmuidx_ra(env, val >> 24, addr, midx, ra);
cpu_stw_be_mmuidx_ra(env, val >> 16, addr + 1, midx, ra);
break;
case 2:
cpu_stw_be_mmuidx_ra(env, val >> 16, addr, midx, ra);
break;
case 3:
cpu_stb_mmuidx_ra(env, val >> 24, addr, midx, ra);
break;
}
}
void helper_swl_le(env, val, addr, midx)
{
uintptr_t ra = GETPC();
/*
* We want to use stw and stl for atomicity, but want any
* fault to report ADDR, not the aligned address.
*/
probe_write(env, addr, 0, midx, ra);
switch (addr & 3) {
case 3:
cpu_stl_le_mmuidx_ra(env, val, addr - 3, midx, ra);
break;
case 1:
cpu_stw_le_mmuidx_ra(env, val >> 16, addr - 1, midx, ra);
break;
case 2:
cpu_stw_le_mmuidx_ra(env, val >> 8, addr - 2, midx, ra);
/* fall through */
case 0:
cpu_stb_mmuidx_ra(env, val >> 24, addr, midx, ra);
break;
}
}
etc.
r~
- [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian(), Philippe Mathieu-Daudé, 2021/08/18
- [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function, Philippe Mathieu-Daudé, 2021/08/18
- [PATCH 3/5] target/mips: Replace GET_LMASK64() macro by get_lmask(64) function, Philippe Mathieu-Daudé, 2021/08/18
- [PATCH 4/5] target/mips: Store CP0_Config0 in DisasContext, Philippe Mathieu-Daudé, 2021/08/18
- [PATCH 5/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian(), Philippe Mathieu-Daudé, 2021/08/18