Floating-point assembly and disassembly bugs on armel
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro Binutils |
Fix Released
|
Low
|
Unassigned | ||
binutils (Ubuntu) |
Fix Released
|
Low
|
Unassigned |
Bug Description
Binary package hint: binutils
Distro: lucid
Package: binutils (2.20-5ubuntu1)
Architecture: armel
Two low-priority issues here:
1) gas wrongly accepts an address index for the NEON element loads and stores VLD1, VST2 etc. gas also wrongly accepts e.g., vld1 d0, <label> (where <label> is a local literal label and implies [pc, <some offset>]).
There is no instruction encoding allowing an offset in these instructions: gas should throw an error.
2) binutils incorrectly annotates the target address when disassembling pc-relative vldr instructions in Thumb-2. The annotation is done as if the CPU did not align PC down to a word boundary before doing the address calculation; however, the assembled code looks correct.
The same problem might apply to other 32-bit instruction encodings, bit I'm not aware of any except for vldr and vstr at the moment (pc-relative vstr is not permitted in Thumb-2 by the architecture and should possibly be rejected by the assembler).
See the attached file for a test case.
I get:
$ as -mfpu=neon -o vldr-dis.o vldr-dis.s
$ objdump -d vldr-dis.o
...
Disassembly of section .text:
00000000 <f>:
0: ed9f 0b0e vldr d0, [pc, #56] ; 3c <float>
4: bf00 nop
6: ed9f 0b0d vldr d0, [pc, #52] ; 3e <float+0x2>
^^ should be ... ; 3c <float>
a: bf00 nop
c: ed8f 0b0b vstr d0, [pc, #44] ; 3c <float>
10: bf00 nop
12: ed8f 0b0a vstr d0, [pc, #40] ; 3e <float+0x2>
^^ should be ... ; 3c <float>; however, use of the pc as base register is not permitted in Thumb; gas should probably reject this instruction.
16: bf00 nop
18: f8df 0020 ldr.w r0, [pc, #32] ; 3c <float>
1c: bf00 nop
1e: f8df 001c ldr.w r0, [pc, #28] ; 3c <float>
22: bf00 nop
24: f92f 070f vld1.8 {d0}, [pc]
^^ gas should have rejected this instruction, which had an offset in the source
28: bf00 nop
2a: f90f 070f vst1.8 {d0}, [pc]
^^ gas should have rejected this instruction, which had an offset in the source
2e: bf00 nop
30: f92f 070f vld1.8 {d0}, [pc]
^^ gas should have rejected this instruction, which had an offset in the source
34: bf00 nop
36: f92f 070f vld1.8 {d0}, [pc]
^^ gas should have rejected this instruction, which had an offset in the source
3a: 46c0 nop ; (mov r8, r8)
0000003c <float>:
...
tags: | added: toolchain |
tags: | added: armv7 thumb |
Changed in binutils-linaro: | |
importance: | Undecided → Low |
Changed in binutils (Ubuntu): | |
importance: | Undecided → Low |
status: | New → Confirmed |
Changed in binutils-linaro: | |
status: | New → Confirmed |
Changed in binutils-linaro: | |
status: | Confirmed → Triaged |
Changed in binutils-linaro: | |
status: | Triaged → Fix Committed |
Changed in binutils-linaro: | |
status: | Fix Committed → Fix Released |
The situation seems to be better in gas 2.21 (binutils- arm-linux- gnueabi 2.21-1ubuntu4cr oss1.55)
arm-linux- gnueabi- as vldr-dis.s -mfpu=neon -(.&-4) -4+float] ' -(.&-4) -4+float] '
vldr-dis.s: Assembler messages:
vldr-dis.s:17: Error: r15 not allowed here -- `vld1.8 d0,float'
vldr-dis.s:19: Error: r15 not allowed here -- `vst1.8 d0,float'
vldr-dis.s:21: Error: r15 not allowed here -- `vld1.8 d0,[pc,
vldr-dis.s:23: Error: r15 not allowed here -- `vld1.8 d0,[pc,
so then I replaced those four with vldr d0, float (to keep offsets the same as the original), reassembled and objdump'd it
which gives:
0: ed9f 0b0e vldr d0, [pc, #56] ; 3c <float>
4: 46c0 nop ; (mov r8, r8)
6: ed9f 0b0d vldr d0, [pc, #52] ; 3c <float>
a: 46c0 nop ; (mov r8, r8)
c: ed8f 0b0b vstr d0, [pc, #44] ; 3c <float>
10: 46c0 nop ; (mov r8, r8)
12: ed8f 0b0a vstr d0, [pc, #40] ; 3c <float>
16: 46c0 nop ; (mov r8, r8)
18: f8df 0020 ldr.w r0, [pc, #32] ; 3c <float>
1c: 46c0 nop ; (mov r8, r8)
1e: f8df 001c ldr.w r0, [pc, #28] ; 3c <float>
22: 46c0 nop ; (mov r8, r8)
24: ed9f 0b05 vldr d0, [pc, #20] ; 3c <float>
28: 46c0 nop ; (mov r8, r8)
2a: ed9f 0b04 vldr d0, [pc, #16] ; 3c <float>
2e: 46c0 nop ; (mov r8, r8)
30: ed9f 0b02 vldr d0, [pc, #8] ; 3c <float>
34: 46c0 nop ; (mov r8, r8)
36: ed9f 0b01 vldr d0, [pc, #4] ; 3c <float>
3a: 46c0 nop ; (mov r8, r8)
so I think the offsets are now as you expect.
So I think that the only one left is that it should be disallowing pc relative vstr's
Dave