Bug 13843

Summary: Negative immediate for vmov fails on 32-bit host
Product: binutils Reporter: Andrew Stubbs <ams>
Component: gasAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: amodra
Priority: P2    
Version: 2.24   
Target Milestone: ---   
Host: i686-pc-linux-gnu armv7l-unknown-linux-gnu Target: arm
Build: Last reconfirmed:
Attachments: patch

Description Andrew Stubbs 2012-03-14 12:07:29 UTC
These two inputs are supposed to give the same output:

        vmov.i64        d21, #-65536  @ di
        vmov.i64        d21, #0xffffffffffff0000  @ di

But the actual disassembly looks like this:

   0:   efc0 5e3c       vmov.i64        d21, #0x00000000ffff0000
   4:   ffc7 5e3c       vmov.i64        d21, #0xffffffffffff0000

The negative decimal constant has been truncated to 32 bits.

This bug appears to only occur on 32-bit hosts. (I've reproduced it on i686 and armv7a, but not on x86_64.)

This may be related to bug 12715, although that's already been fixed.
Comment 1 Alan Modra 2012-03-14 15:27:59 UTC
Created attachment 6286 [details]
patch

This hack works by virtue of X_unsigned only being false when the expression parser sees a unary negate.  So -65536 can be distinguished from 0xffff0000 even on a 32-bit host.
Comment 2 Andrew Stubbs 2012-03-14 16:19:19 UTC
I can confirm that the patch fixes the -65536 case, but it still fails for -262144 and -1048576, etc.

It ought to be possible to represent any 64-bit number in which each byte consists of either 0x00 or 0xff.
Comment 3 Alan Modra 2012-03-14 22:35:34 UTC
What makes you think -262144 and -1048576 are valid?  Neither match "each byte
consists of either 0x00 or 0xff" or any of the other valid immediates specified in the arm architecture manual for vmov as far as I can see.
Comment 4 Andrew Stubbs 2012-03-17 20:40:46 UTC
Ah, ok, it appears my maths is mysteriously broken. On a second inspection, the patch seems fine.