https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127548
--- Comment #1 from Jeevitha <jeevitha at gcc dot gnu.org> ---
vec_sldb — Vector Shift Left Double Bit Immediate
r = vec_sldb (a, b, c)
Purpose:
Shifts a double-wide vector left by up to 7 bits and returns the leftmost 128
bits of the result.
Result value:
Let v be the concatenation of a and b, with a on the left. Let w be v shifted
left by the number of bits specified by c. Then r is set to the leftmost 128
bits of w.
Endian considerations:
The semantics of this built-in function differ for big-endian and little-endian
targets, since the concatenation of a and b is done in big-endian fashion (left
to right).
Instruction semantics
vsldbi VRT,VRA,VRB,SH
if MSR.VEC=0 then Vector_Unavailable()
vsrc.qword[0] ← VSR[VRA+32]
vsrc.qword[1] ← VSR[VRB+32]
VSR[VRT+32] ← vsrc.bit[SH:SH+127]
---
Testcase:
vector signed char vresult_char;
vector signed char expected_vresult_char;
vector signed char src_va_char;
vector signed char src_vb_char;
src_va_char =
(vector signed char) { 0, 2, 4, 6, 8, 10, 12, 14,
16, 18, 20, 22, 24, 26, 28, 30 };
src_vb_char =
(vector signed char) { 10, 20, 30, 40, 50, 60, 70, 80,
90, 100, 110, 120, 130, 140, 150, 160 };
vresult_char =
(vector signed char) { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
expected_vresult_char =
(vector signed char) { 80, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14 };
vresult_char = vec_sldb (src_va_char, src_vb_char, 7);
vec_sldb generates: vsldbi v0,v0,v1,7
On Big-endian:
Before executing vsldbi:
p/x $v0
$1 = {uint128 = 0x20406080a0c0e10121416181a1c1e,
v4_float = {0x20406, 0x80a0c0e, 0x10121416, 0x181a1c1e},
v4_int32 = {0x20406, 0x80a0c0e, 0x10121416, 0x181a1c1e},
v8_int16 = {0x2, 0x406, 0x80a, 0xc0e,
0x1012, 0x1416, 0x181a, 0x1c1e},
v16_int8 = {0x0, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe,
0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e}}
p/x $v1
$2 = {uint128 = 0xa141e28323c46505a646e78828c96a0,
v4_float = {0xa141e28, 0x323c4650, 0x5a646e78, 0x828c96a0},
v4_int32 = {0xa141e28, 0x323c4650, 0x5a646e78, 0x828c96a0},
v8_int16 = {0xa14, 0x1e28, 0x323c, 0x4650,
0x5a64, 0x6e78, 0x828c, 0x96a0},
v16_int8 = {0xa, 0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50,
0x5a, 0x64, 0x6e, 0x78, 0x82, 0x8c, 0x96, 0xa0}}
After:
vsldbi v0,v0,v1,7
we get:
p/x $v0
$3 = {uint128 = 0x102030405060708090a0b0c0d0e0f05,
v4_float = {0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f05},
v4_int32 = {0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f05},
v8_int16 = {0x102, 0x304, 0x506, 0x708,
0x90a, 0xb0c, 0xd0e, 0xf05},
v16_int8 = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x5}}
The concatenation is:
A CONCAT B:
0x20406080a0c0e10121416181a1c1e
|
0xa141e28323c46505a646e78828c96a0
In binary:
00100000010000000110000010000000101000001100000011100001000000010010000101000001011000011000000110100001110000011110
concat
00001010000101000001111000101000001100100011110001000110010100000101101001100100011011100111100010000010100011001001011010100000
For SH=7
the instruction selects: vsrc.bit[7:134]
Therefore, it takes:
bits 7:127 from A
bits 128:134 from B
The resulting 128 bits are:
[A]001000000010000001100000010000000101000001100000011100000100000001001000010100000101100001100000011010000111000001111010
[B] 0000101
which corresponds to: 0x102030405060708090A0B0C0D0E0F05
On Little-endian
Before executing vsldbi:
p/x $v0
$1 = {uint128 = 0x1e1c1a18161412100e0c0a0806040200,
v4_float = {0x6040200, 0xe0c0a08, 0x16141210, 0x1e1c1a18},
v4_int32 = {0x6040200, 0xe0c0a08, 0x16141210, 0x1e1c1a18},
v8_int16 = {0x200, 0x604, 0xa08, 0xe0c,
0x1210, 0x1614, 0x1a18, 0x1e1c},
v16_int8 = {0x0, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe,
0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e}}
p/x $v1
$2 = {uint128 = 0xa0968c82786e645a50463c32281e140a,
v4_float = {0x281e140a, 0x50463c32, 0x786e645a, 0xa0968c82},
v4_int32 = {0x281e140a, 0x50463c32, 0x786e645a, 0xa0968c82},
v8_int16 = {0x140a, 0x281e, 0x3c32, 0x5046,
0x645a, 0x786e, 0x8c82, 0xa096},
v16_int8 = {0xa, 0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50,
0x5a, 0x64, 0x6e, 0x78, 0x82, 0x8c, 0x96, 0xa0}}
The concatenation is:
A CONCAT B:
0x1e1c1a18161412100e0c0a0806040200
|
0xa0968c82786e645a50463c32281e140a
In binary:
00011110000111000001101000011000000101100001010000010010000100000000111000001100000010100000100000000110000001000000001000000000
concat
10100000100101101000110010000010011110000110111001100100010110100101000001000110001111000011001000101000000111100001010000001010
The selected bits are:
[A]0000111000001101000011000000101100001010000010010000100000000111000001100000010100000100000000110000001000000001000000000
[B]1010000
which gives:
0xE0D0C0B0A0908070605040302010050
Hence, the tests fails on big-endian PowerPC because its expected value assumes
the little-endian representation of the vector.