Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Support of thumb2's modified immediate assembly syntax is incomplete #28646

Closed Quuxplusone closed 7 years ago

Quuxplusone commented 8 years ago
Bugzilla Link PR28647
Status RESOLVED FIXED
Importance P normal
Reported by laszio@google.com
Reported on 2016-07-21 14:15:58 -0700
Last modified on 2017-06-05 09:22:18 -0700
Version trunk
Hardware All All
CC heniol33t@wp.pl, james@jamesmolloy.co.uk, llvm-bugs@lists.llvm.org, smithp352@googlemail.com, srhines@google.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
$ llvm-mc -triple=armv7a-linux-gnueabi -o test.o test.s
test.s:7:12: error: invalid operand for instruction
 sub r3,r3,#.L1-.L2

@@@ test.s @@@
.text
.syntax unified
.thumb
.arch armv7-a

.L1:
 sub r3,r3,#.L1-.L2
.L2:
Quuxplusone commented 7 years ago
Some initial thoughts.

This example in its full generality is difficult for llvm-mc to handle. The
main problems are:
1.) The result of .L1 - .L2 cannot be evaluated at the point that it is used as
L2 hasn't been encountered yet.
2.) The result of .L1 - .L2 is negative but the data processing instructions
can only accept an unsigned immediate.

The first problem can be solved by using a fixup, so the invalid operand error
message implies that we are missing a fixup.

The second problem is much more difficult to solve. We can usually flip a sub
into an add and vice-versa when we know that the immediate is negative.
Unfortunately at the time that we know that the immediate is negative we have
already committed to the opcode [*].

For example in test.s, if we use ARM rather than Thumb then I get the error
message
test.s:7:2: error: out of range immediate fixup value
 sub r3,r3,#.L1-.L2

I think it could be possible to add a fixup that would only accept positive
expression results (like ARM), however I don't think that there would be an
easy way to do the add/sub transition.

Would it be reasonable to rewrite the example as:
.L1
 add r3, r3,#.L2-.L1
.L2
?

[*]
The last time I looked about a year ago, when trying to implement the adrl
pseudo instruction, the fixup could OR bits into the instruction bit-pattern,
but it could not clear them so there was no way of changing the opcode from add
to sub.
Quuxplusone commented 7 years ago

Thanks for looking into this. The test case is simplified from openssl, where the original resulted immediates are all positive. It's my fault to accidentally overly generalize the test case. Sorry for the typo.

By the way, llvm-mc seems to accept the negative immediate but clang doesn't. Not sure if that is another problem or not.

Quuxplusone commented 7 years ago
I've posted https://reviews.llvm.org/D33492 for a potential fix when the
expression resolves to a positive constant expression at assembly time. The fix
should permit:
.text
.syntax unified
.thumb
.arch armv7-a

.L1:
 sub r3,r3,#.L2-.L1
.L2:

but not #.L1-.L2.
Quuxplusone commented 7 years ago

Committed r304702, resolving as fixed for expressions that evaluate to non-negative numbers.