Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

llvm-mc treats .n suffix as .w suffix for ADC #13877

Open Quuxplusone opened 12 years ago

Quuxplusone commented 12 years ago
Bugzilla Link PR13803
Status REOPENED
Importance P enhancement
Reported by Greg Fitzgerald (garious@gmail.com)
Reported on 2012-09-09 19:18:17 -0700
Last modified on 2021-06-11 10:11:33 -0700
Version trunk
Hardware PC Windows NT
CC compnerd@compnerd.org, garious@gmail.com, john.brawn@arm.com, kristof.beyls@arm.com, llvm-bugs@lists.llvm.org, ndesaulniers@google.com, rprichard@google.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Fails:

  echo "adc.w r0, r1, #1" | llvm-mc -triple=thumbv7 -show-encoding

Also fails for 'sbc.w' and its variants.

Workaround:

  echo "adc r0, r1, #1" | llvm-mc -triple=thumbv7 -show-encoding

Awkward workaround, use ".n", but it is still encoded with 32-bits:

  echo "adc.n r0, r1, #1" | llvm-mc -triple=thumbv7 -show-encoding
Quuxplusone commented 9 years ago

This must be an extension. As per the ARM ARM:

ADC{S}.W , {, }

is what you are trying to use. is a register shift, which requires the shift type (LSL, LSR, ASR, ROR) or RRX for a non-constant applied.

Is there a strong reason to support this extension? Can you indicate what assemblers support this extension, and why you feel this is to support?

Quuxplusone commented 9 years ago
The syntax for encoding T1 is ADC{S}<c>.W, but the assembler syntax for ADC
(immediate) is

  ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>

where <q> is .N or .W (page A8-301 of the ARMv7-A/R ARMARM revision C.c).

In the ARMARM the .W suffix is listed in the encoding if it's necessary to
distinguish it from other encodings, but in the assembly syntax it's permitted
even when it's not needed to distinguish between encodings (see section A8.2
"Standard assembler syntax fields").
Quuxplusone commented 9 years ago

The syntax for encoding T1 is ADC{S}.W

Correction: that should have been "The syntax for encoding T2 of ADC (register) is ADC{S}.W"

Quuxplusone commented 3 years ago
LLVM seems to be doing this:
 - ".n" suffixes are ignored: "foo.n" is assembled just like "foo", even if "foo" is wide
 - A ".w" suffix needs to be handled via a special alias in the assembler, and the alias support is spotty.

See bug #50664, bug #49118,
https://gist.github.com/rprichard/2a601c3dd1b281f953b4e08b5a9361bb.

The GNU assembler instead seems to treat the ".n"/".w" suffix as a constraint.
If the instruction could be encoded either way, then the assembler selects the
encoding matching the suffix. Otherwise, if the suffix doesn't match the
encoding, there's an assembler error. This behavior makes a lot more sense to
me, but I'm not sure if there's an standard LLVM is trying to follow.