mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-24 06:28:12 +00:00
target/arm: Extend vec_reg_offset to larger sizes
Rearrange the arithmetic so that we are agnostic about the total size of the vector and the size of the element. This will allow us to index up to the 32nd byte and with 16-byte elements. Backports commit 66f2dbd783d0b6172043e3679171421b2d0bac11 from qemu
This commit is contained in:
parent
0a23259560
commit
4dc2b5ea79
1 changed files with 17 additions and 9 deletions
|
@ -67,18 +67,26 @@ static inline void assert_fp_access_checked(DisasContext *s)
|
||||||
static inline int vec_reg_offset(DisasContext *s, int regno,
|
static inline int vec_reg_offset(DisasContext *s, int regno,
|
||||||
int element, TCGMemOp size)
|
int element, TCGMemOp size)
|
||||||
{
|
{
|
||||||
int offs = 0;
|
int element_size = 1 << size;
|
||||||
|
int offs = element * element_size;
|
||||||
#ifdef HOST_WORDS_BIGENDIAN
|
#ifdef HOST_WORDS_BIGENDIAN
|
||||||
/* This is complicated slightly because vfp.zregs[n].d[0] is
|
/* This is complicated slightly because vfp.zregs[n].d[0] is
|
||||||
* still the low half and vfp.zregs[n].d[1] the high half
|
* still the lowest and vfp.zregs[n].d[15] the highest of the
|
||||||
* of the 128 bit vector, even on big endian systems.
|
* 256 byte vector, even on big endian systems.
|
||||||
* Calculate the offset assuming a fully bigendian 128 bits,
|
*
|
||||||
* then XOR to account for the order of the two 64 bit halves.
|
* Calculate the offset assuming fully little-endian,
|
||||||
|
* then XOR to account for the order of the 8-byte units.
|
||||||
|
*
|
||||||
|
* For 16 byte elements, the two 8 byte halves will not form a
|
||||||
|
* host int128 if the host is bigendian, since they're in the
|
||||||
|
* wrong order. However the only 16 byte operation we have is
|
||||||
|
* a move, so we can ignore this for the moment. More complicated
|
||||||
|
* operations will have to special case loading and storing from
|
||||||
|
* the zregs array.
|
||||||
*/
|
*/
|
||||||
offs += (16 - ((element + 1) * (1 << size)));
|
if (element_size < 8) {
|
||||||
offs ^= 8;
|
offs ^= 8 - element_size;
|
||||||
#else
|
}
|
||||||
offs += element * (1 << size);
|
|
||||||
#endif
|
#endif
|
||||||
offs += offsetof(CPUARMState, vfp.zregs[regno]);
|
offs += offsetof(CPUARMState, vfp.zregs[regno]);
|
||||||
assert_fp_access_checked(s);
|
assert_fp_access_checked(s);
|
||||||
|
|
Loading…
Reference in a new issue