Wind River Support Network


LIN6-9604 : problem with qemuppc move to vscr instruction

Created: Mar 23, 2015    Updated: Dec 3, 2018
Resolved Date: Mar 29, 2015
Found In Version:
Fix Version:
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() {
			"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: 
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
(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).

Steps to Reproduce

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.

Other Downloads

Live chat