target-m68k: Implement bfffo

Signed-off-by: Richard Henderson <rth@twiddle.net>
Message-Id: <1479242669-25852-1-git-send-email-rth@twiddle.net>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
Richard Henderson 2016-11-15 21:44:29 +01:00 committed by Laurent Vivier
parent f2224f2c9a
commit a45f1763cc
3 changed files with 62 additions and 1 deletions

View file

@ -654,3 +654,24 @@ uint32_t HELPER(bfset_mem)(CPUM68KState *env, uint32_t addr,
return ((data & mask) << d.bofs) >> 32;
}
uint32_t HELPER(bfffo_reg)(uint32_t n, uint32_t ofs, uint32_t len)
{
return (n ? clz32(n) : len) + ofs;
}
uint64_t HELPER(bfffo_mem)(CPUM68KState *env, uint32_t addr,
int32_t ofs, uint32_t len)
{
uintptr_t ra = GETPC();
struct bf_data d = bf_prep(addr, ofs, len);
uint64_t data = bf_load(env, d.addr, d.blen, ra);
uint64_t mask = -1ull << (64 - d.len) >> d.bofs;
uint64_t n = (data & mask) << d.bofs;
uint32_t ffo = helper_bfffo_reg(n >> 32, ofs, d.len);
/* Return FFO in the low word and N in the high word.
Note that because of MASK and the shift, the low word
is already zero. */
return n | ffo;
}