Fixed
Created: Mar 23, 2015
Updated: Dec 3, 2018
Resolved Date: Mar 29, 2015
Found In Version: 6.0.0.16
Fix Version: 6.0.0.19
Severity: Standard
Applicable for: Wind River Linux 6
Component/s: BSP
After debugging a valgrind sanity check on the altivec vscr register which fails, the gdb commands indicated that either
1) gdb was broken (unlikely since valgrind tests show code failure not debugger failure)
2) the toolchain is broken and doesn't generate the correct opcodes, or
3) the qemuppc altivec mtvscr implementation is broken.
I have included a short reproducer here:
void main() {
asm(
"vspltisb 3,-1\n"
"mtvscr 3\n;"
"vspltisb 3,0\n"
"mtvscr 3\n;"
);
}
The code was built and tested with the same switches that build the qemuppc platform, -m32 -mhard-float -mcpu=7400.
The documentation for the Alitvec Vector Status and Control Register:
http://cache.freescale.com/files/32bit/doc/ref_manual/ALTIVECPEM.pdf
Figure 2-4 shows the field numbers but Table 2-1 shows that there are only 4 fields, 2 R/W fields the Non-Java bit (non-IEEE floating point) and the Saturation bit. The other fields return 0 if set to 0 and otherwise return indeterminate values. The reproducer uses the 128 bit vector register 3 to set the 32bit VSCR register to all 1's. This should necessarily set the 2 writable bit fields, but examination with gdb shows the following:
(gdb) disass main
Dump of assembler code for function main:
0x10000474 <+0>: stwu r1,-32(r1)
0x10000478 <+4>: stw r31,28(r1)
0x1000047c <+8>: mr r31,r1
0x10000480 <+12>: vspltisb v3,-1
0x10000484 <+16>: mtvscr v3
0x10000488 <+20>: vspltisb v3,0
0x1000048c <+24>: mtvscr v3
0x10000490 <+28>: addi r11,r31,32
0x10000494 <+32>: lwz r31,-4(r11)
0x10000498 <+36>: mr r1,r11
0x1000049c <+40>: blr
End of assembler dump.
b main
r(gdb) info reg vscr
vscr 0x10000 65536
# The Non-Java bit is on, which refers to returning 0 for denormalized
# values, 0'g registers on underflow exceptions and other special states.
=> 0x10000480 <main+12>: vspltisb v3,-1
(gdb) si
(gdb) info reg $vr3
vr3 {uint128 = 0xffffffffffffffffffffffffffffffff,
v4_float = {0x80000000, 0x80000000, 0x80000000, 0x80000000},
v4_int32 = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
v8_int16 = {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
v16_int8 = { 0xff <repeats 16 times>}}
# vr3 is set to all 1's
1: x/i $pc
=> 0x10000484 <main+16>: mtvscr v3
si
(gdb) info reg $vscr
vscr 0x0 0
The vector status control register is still 0 but the two writeable fields should have been set. This is not the exact same anomaly seen with valgrind; which can not set vcsr to 0 (using the same 2 instructions but zeroing vr3).
configure --enable-board=qemuppc --enable-build=debug --enable-kernel=standard --enable-rootfs=glibc-small
make fs
In wb4 or using the toolchain directly compile the attached source file. Debug and step through the first 2 source assembler instructions. Note that 'info reg $vscr' shows 0 instead of the two writable fields set to 1.