mirror of https://github.com/xemu-project/xemu.git
target-ppc: Altivec 2.07: Change Bit Masks to Support 64-bit Rotates and Shifts
Existing code in the VROTATE, VSL and VSR macros for the Altivec rotate and shift helpers uses a formula to compute a bit mask used to extract the rotate/shift amount from the VRB register. What is desired is: mask = (1 << (3 + log2(sizeof(element)))) - 1 but what is implemented is: mask = (1 << (3 + (sizeof(element)/2))) - 1 This produces correct answers when "element" is uint8_t, uint16_t or uint_32t. But it breaks down when element is uint64_t. This patch corrects the situation. Since the mask is known at compile time, the macros are changed to simply accept the mask as an argument. Subsequent patches in this series will add double-word variants of rotates and shifts and thus take advantage of this fix. Signed-off-by: Tom Musta <tommusta@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
e0ffe77f27
commit
818692ff95
|
@ -1128,23 +1128,20 @@ VRFI(p, float_round_up)
|
||||||
VRFI(z, float_round_to_zero)
|
VRFI(z, float_round_to_zero)
|
||||||
#undef VRFI
|
#undef VRFI
|
||||||
|
|
||||||
#define VROTATE(suffix, element) \
|
#define VROTATE(suffix, element, mask) \
|
||||||
void helper_vrl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
|
void helper_vrl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
|
||||||
{ \
|
{ \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
|
for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
|
||||||
unsigned int mask = ((1 << \
|
|
||||||
(3 + (sizeof(a->element[0]) >> 1))) \
|
|
||||||
- 1); \
|
|
||||||
unsigned int shift = b->element[i] & mask; \
|
unsigned int shift = b->element[i] & mask; \
|
||||||
r->element[i] = (a->element[i] << shift) | \
|
r->element[i] = (a->element[i] << shift) | \
|
||||||
(a->element[i] >> (sizeof(a->element[0]) * 8 - shift)); \
|
(a->element[i] >> (sizeof(a->element[0]) * 8 - shift)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
VROTATE(b, u8)
|
VROTATE(b, u8, 0x7)
|
||||||
VROTATE(h, u16)
|
VROTATE(h, u16, 0xF)
|
||||||
VROTATE(w, u32)
|
VROTATE(w, u32, 0x1F)
|
||||||
#undef VROTATE
|
#undef VROTATE
|
||||||
|
|
||||||
void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
|
void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
|
||||||
|
@ -1225,23 +1222,20 @@ VSHIFT(r, RIGHT)
|
||||||
#undef LEFT
|
#undef LEFT
|
||||||
#undef RIGHT
|
#undef RIGHT
|
||||||
|
|
||||||
#define VSL(suffix, element) \
|
#define VSL(suffix, element, mask) \
|
||||||
void helper_vsl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
|
void helper_vsl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
|
||||||
{ \
|
{ \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
|
for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
|
||||||
unsigned int mask = ((1 << \
|
|
||||||
(3 + (sizeof(a->element[0]) >> 1))) \
|
|
||||||
- 1); \
|
|
||||||
unsigned int shift = b->element[i] & mask; \
|
unsigned int shift = b->element[i] & mask; \
|
||||||
\
|
\
|
||||||
r->element[i] = a->element[i] << shift; \
|
r->element[i] = a->element[i] << shift; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
VSL(b, u8)
|
VSL(b, u8, 0x7)
|
||||||
VSL(h, u16)
|
VSL(h, u16, 0x0F)
|
||||||
VSL(w, u32)
|
VSL(w, u32, 0x1F)
|
||||||
#undef VSL
|
#undef VSL
|
||||||
|
|
||||||
void helper_vsldoi(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t shift)
|
void helper_vsldoi(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t shift)
|
||||||
|
@ -1325,26 +1319,22 @@ VSPLTI(h, s16, int16_t)
|
||||||
VSPLTI(w, s32, int32_t)
|
VSPLTI(w, s32, int32_t)
|
||||||
#undef VSPLTI
|
#undef VSPLTI
|
||||||
|
|
||||||
#define VSR(suffix, element) \
|
#define VSR(suffix, element, mask) \
|
||||||
void helper_vsr##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
|
void helper_vsr##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
|
||||||
{ \
|
{ \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
|
for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
|
||||||
unsigned int mask = ((1 << \
|
|
||||||
(3 + (sizeof(a->element[0]) >> 1))) \
|
|
||||||
- 1); \
|
|
||||||
unsigned int shift = b->element[i] & mask; \
|
unsigned int shift = b->element[i] & mask; \
|
||||||
\
|
|
||||||
r->element[i] = a->element[i] >> shift; \
|
r->element[i] = a->element[i] >> shift; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
VSR(ab, s8)
|
VSR(ab, s8, 0x7)
|
||||||
VSR(ah, s16)
|
VSR(ah, s16, 0xF)
|
||||||
VSR(aw, s32)
|
VSR(aw, s32, 0x1F)
|
||||||
VSR(b, u8)
|
VSR(b, u8, 0x7)
|
||||||
VSR(h, u16)
|
VSR(h, u16, 0xF)
|
||||||
VSR(w, u32)
|
VSR(w, u32, 0x1F)
|
||||||
#undef VSR
|
#undef VSR
|
||||||
|
|
||||||
void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
|
void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
|
||||||
|
|
Loading…
Reference in New Issue