Ubuntu

Floating-point assembly and disassembly bugs on armel

Reported by Dave Martin on 2010-02-04
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro Binutils
Low
Unassigned
binutils (Ubuntu)
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>:
        ...

Matthias Klose (doko) on 2010-06-17
tags: added: toolchain
Loïc Minier (lool) on 2010-07-12
tags: added: armv7 thumb
Changed in binutils-linaro:
importance: Undecided → Low
Matthias Klose (doko) on 2010-07-21
Changed in binutils (Ubuntu):
importance: Undecided → Low
status: New → Confirmed

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
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers