Floating-point assembly and disassembly bugs on armel

Bug #517081 reported by Dave Martin
8
This bug affects 1 person
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>:
        ...

Revision history for this message
Dave Martin (dave-martin-arm) wrote :
Matthias Klose (doko)
tags: added: toolchain
Loïc Minier (lool)
tags: added: armv7 thumb
Changed in binutils-linaro:
importance: Undecided → Low
Matthias Klose (doko)
Changed in binutils (Ubuntu):
importance: Undecided → Low
status: New → Confirmed
Revision history for this message
Dr. David Alan Gilbert (davidgil-uk) wrote :

The situation seems to be better in gas 2.21 (binutils-arm-linux-gnueabi 2.21-1ubuntu4cross1.55)

arm-linux-gnueabi-as vldr-dis.s -mfpu=neon
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,-(.&-4)-4+float]'
vldr-dis.s:23: Error: r15 not allowed here -- `vld1.8 d0,[pc,-(.&-4)-4+float]'

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

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
Revision history for this message
Matthias Klose (doko) wrote :

fixed in 14.04 LTS

Changed in binutils (Ubuntu):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.