Bug 203950 - clang mis-assembles immediate operands
Summary: clang mis-assembles immediate operands
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-arm (Nobody)
Depends on:
Reported: 2015-10-22 11:22 UTC by Peter Jeremy
Modified: 2015-10-22 19:27 UTC (History)
1 user (show)

See Also:

ARM AES code generated by OpenSSL perl script. (22.58 KB, text/plain)
2015-10-22 11:22 UTC, Peter Jeremy
no flags Details
perl script to generate ARM immediate constants (1.23 KB, application/x-perl)
2015-10-22 19:27 UTC, Peter Jeremy
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Jeremy freebsd_committer 2015-10-22 11:22:58 UTC
Created attachment 162344 [details]
ARM AES code generated by OpenSSL perl script.

Whilst experimenting with the OpenSSL ARM assembler code, I discovered that clang is incorrectly handling immediate operands.

This is using:
% cc -c aes_arm.s
% objdump -d aes_arm.o | less
% cc -v
FreeBSD clang version 3.6.1 (tags/RELEASE_361/final 237755) 20150525
Target: armv6--freebsd11.0-gnueabihf
Thread model: posix

The source code (attached) includes:
        sub     r3,pc,#8                @ AES_encrypt
        stmdb   sp!,{r1,r4-r12,lr}
        mov     r12,r0          @ inp
        mov     r11,r2
        sub     r10,r3,#AES_encrypt-AES_Te      @ Te

#AES_encrypt-AES_Te is 1344 or 0x540.  clang compiles this subtraction to 0xe243a540 - which decompiles to:
e243a540        sub     sl, r3, #268435456      ; 0x10000000
because the 12-bit immediate field is not a direct binary number but is a 4-bit rotation followed by a 8-bit binary value.  A correct value for this field would be (eg) 0xe54.  Note that as(1) gets compiles the instruction to:
e243ad15        sub     sl, r3, #1344   ; 0x540
Comment 1 Peter Jeremy freebsd_committer 2015-10-22 19:27:55 UTC
Created attachment 162367 [details]
perl script to generate ARM immediate constants

Some experimenting with the attached script shows that the C compiler correctly handles constants in the C to object and C to asm cases but not the asm to object case.