public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Regression: operand size mismatch for `push'
@ 2023-10-03 20:22 Andrew Cooper
  2023-10-16  7:54 ` Jan Beulich
  0 siblings, 1 reply; 2+ messages in thread
From: Andrew Cooper @ 2023-10-03 20:22 UTC (permalink / raw)
  To: binutils, tdevries, H.J. Lu, Jan Beulich

Hello,

I think this is related to
https://sourceware.org/bugzilla/show_bug.cgi?id=30928 but I can't bisect
myself.  It did regress between 2.39 and 2.41

$ /local/bin/bin-2.39/bin/as push.S -o push.o
$ /local/bin/bin-2.41/bin/as push.S -o push.o
push.S: Assembler messages:
push.S:5: Error: operand size mismatch for `push'

$ cat push.S
        .text
        .code64
code64:
        push $0
        push $1f
1:

        .code32
code32:
        push $0
        push $1f
1:


Using `push` without an explicit suffix is important for writing
bitness-agnostic assembly.  Right now, 2.41's complains are asymmetric,
insisting on a q suffix in 64bit code while not insisting on an l suffix
in 32bit code.

For stack operations, there is always a default operand size (from the
operating mode), which is always the one the programmer wants, given no
indication to the contrary.

The push $imm forms are a little weird.  Stack operations in x86 have an
operand size from 16, 32 or 64 (with 64 and 32 un-encodable in each
others mode).

The 6a (push $imm8) and 68 (push $imm) encodings look like a
byte/non-byte pair, but do not follow the normal operand size rules.  As
such, the use of the wlq suffixes go wrong.

The only way of encoding the $imm16 form is via the 66 prefix or w
suffix, which changes the operand size to 16 and also misaligns the
stack pointer.  The l or q suffixes (which result in no prefix) retain
the default operand size, and apply equally to the byte and non-byte forms.

Despite experimenting, I can't find a way of spelling `push $0` that
results in the 68 00 00 00 00 form.  push.d32 does silence the suffix
warning, but neither .d32 nor .d8 force the 1 or 4 byte immediate
forms.  The form chosen is always based on range, unless there's a
relocation in which case the $imm32 form is used.


This is clearly a tangled part of parsing, but insisting on a q suffix
when the operand size is unambiguous does adversely impact existing
code, and the fact that an l suffix is not insisted upon suggests that
this was an oversight rather than an intentional change in behaviour.

Thanks,

~Andrew

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Regression: operand size mismatch for `push'
  2023-10-03 20:22 Regression: operand size mismatch for `push' Andrew Cooper
@ 2023-10-16  7:54 ` Jan Beulich
  0 siblings, 0 replies; 2+ messages in thread
From: Jan Beulich @ 2023-10-16  7:54 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: binutils, tdevries, H.J. Lu

On 03.10.2023 22:22, Andrew Cooper wrote:
> Hello,
> 
> I think this is related to
> https://sourceware.org/bugzilla/show_bug.cgi?id=30928 but I can't bisect
> myself.  It did regress between 2.39 and 2.41
> 
> $ /local/bin/bin-2.39/bin/as push.S -o push.o
> $ /local/bin/bin-2.41/bin/as push.S -o push.o
> push.S: Assembler messages:
> push.S:5: Error: operand size mismatch for `push'
> 
> $ cat push.S
>         .text
>         .code64
> code64:
>         push $0
>         push $1f
> 1:
> 
>         .code32
> code32:
>         push $0
>         push $1f
> 1:
> 
> 
> Using `push` without an explicit suffix is important for writing
> bitness-agnostic assembly.  Right now, 2.41's complains are asymmetric,
> insisting on a q suffix in 64bit code while not insisting on an l suffix
> in 32bit code.

See PR gas/30856 and fb1c10585ead.

Jan

> For stack operations, there is always a default operand size (from the
> operating mode), which is always the one the programmer wants, given no
> indication to the contrary.
> 
> The push $imm forms are a little weird.  Stack operations in x86 have an
> operand size from 16, 32 or 64 (with 64 and 32 un-encodable in each
> others mode).
> 
> The 6a (push $imm8) and 68 (push $imm) encodings look like a
> byte/non-byte pair, but do not follow the normal operand size rules.  As
> such, the use of the wlq suffixes go wrong.
> 
> The only way of encoding the $imm16 form is via the 66 prefix or w
> suffix, which changes the operand size to 16 and also misaligns the
> stack pointer.  The l or q suffixes (which result in no prefix) retain
> the default operand size, and apply equally to the byte and non-byte forms.
> 
> Despite experimenting, I can't find a way of spelling `push $0` that
> results in the 68 00 00 00 00 form.  push.d32 does silence the suffix
> warning, but neither .d32 nor .d8 force the 1 or 4 byte immediate
> forms.  The form chosen is always based on range, unless there's a
> relocation in which case the $imm32 form is used.
> 
> 
> This is clearly a tangled part of parsing, but insisting on a q suffix
> when the operand size is unambiguous does adversely impact existing
> code, and the fact that an l suffix is not insisted upon suggests that
> this was an oversight rather than an intentional change in behaviour.
> 
> Thanks,
> 
> ~Andrew


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-10-16  7:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-03 20:22 Regression: operand size mismatch for `push' Andrew Cooper
2023-10-16  7:54 ` Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).