There is definitely a bug in MOVW.IA (increment after) and MOVW.IBW
(increment before) handling. Generated code has negated offset and
wrong P bit. I can't run all.bash for now because I tried this fix on
slow qemu emulator. No I can test on real Cortex-A9 machine and
compilation fails:
pkg/go/build
cmd/go
./make.bash: line 119: 12656 Segmentation fault "$GOTOOLDIR"/
go_bootstrap clean -i std
I check for ARM assembler code in tree. There is no instructions
with .IB suffix but there are MOVM.IA:
$ find . -name "*_arm.s" -exec grep "\.IA" {} \; -print
MOVM.IA.W [R0-R7], (R(TO))
./pkg/runtime/memclr_arm.s
MOVM.IA.W [R1-R12], (R0)
MOVM.IA.W (R0), [R1-R12]
./pkg/runtime/vlop_arm.s
MOVM.IA.W (R(FROM)), [R1-R8]
MOVM.IA.W [R1-R8], (R(TS))
MOVM.IA.W (R(FROM)), [R(FR0),R(FR1),R(FR2),R(FR3)]
MOVM.IA.W [R(FW0),R(FW1),R(FW2),R(FW3)], (R(TS))
./pkg/runtime/memmove_arm.s
It seems that 5l treats C_PBIT, C_UBIT in MOVM in different way than
for MOVW:
movm:
if(instoffset != 0)
diag("offset must be zero in MOVM");
o1 |= (p->scond & C_SCOND) << 28;
if(p->scond & C_PBIT)
o1 |= 1 << 24;
if(p->scond & C_UBIT)
o1 |= 1 << 23;
if(p->scond & C_SBIT)
o1 |= 1 << 22;
if(p->scond & C_WBIT)
o1 |= 1 << 21;
break;
As you can see C_PBIT and C_UBIT flags are used without any negation.
Because of this it will be hard to fix 5a without changing 5l (and
probably 5c, 5g).