Bug 998 - generates non-optimal instruction...
Summary: generates non-optimal instruction...
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: pre-2.15
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
Depends on: 997
  Show dependency treegraph
Reported: 2005-06-08 20:28 UTC by Alan Larson
Modified: 2022-06-22 06:22 UTC (History)
1 user (show)

See Also:
Host: i386-pc-freebsd
Target: i386
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Alan Larson 2005-06-08 20:28:11 UTC
Computed lengths are used as 32 bit values, even when they are less
than 128.  Symbols assigned values less than 128 and used generate
a one byte immediate in pushl $value, while symbols with computed
lengths appear as 4 byte immediate values, even though they have the
same small value.


azp:68% cat b.s ; as -a b.s -o b.o

msg:    .asciz  "hello world.\n"
msglen = .-msg-1                # determine length, an absolute value
#msglen=msglen & 0xff           # this crashes the assembler if included
foo = 13

        pushl   $13             # this generates a 2 byte instruction
        pushl   $msglen         # this generates 4 bytes for the same
        pushl   $foo            # but this generates 2 bytes
        pushl   msg
GAS LISTING b.s                         page 1

   1                            .text
   3 0000 68656C6C      msg:    .asciz  "hello world.\n"
   3      6F20776F
   3      726C642E
   3      0A00
   4                    msglen = .-msg-1                # determine length, an
absolute value
   5                    #msglen=msglen & 0xff           # this crashes the
assembler if included
   6                    foo = 13
   8 000e 6A0D                  pushl   $13             # this generates a 2
byte instruction
   9 0010 680D0000              pushl   $msglen         # this generates 4 bytes
for the same
   9      00
  10 0015 6A0D                  pushl   $foo            # but this generates 2 bytes
  11 0017 FF350000              pushl   msg
  11      00008D76
  11      00

GAS LISTING b.s                         page 2

                 b.s:3      .text:00000000 msg
                            *ABS*:0000000d msglen
                            *ABS*:0000000d foo

Comment 1 Alan Modra 2005-06-09 06:36:02 UTC
This is a result of delayed expression evaluation.  If you assemble without
listings turned on, the optimal push insn will be chosen.
Comment 2 Alan Modra 2006-03-30 01:05:12 UTC
Some background info I should have added to help people looking through the bug

<bje> alanm: Any opinions on PR 998?
<bje> I gather from your comments that you've stated, "That's the way it is". 
Is there anything more to do here?
<alanm> bje, depends on how much work you want to do.  the problem is that with
listings turned on, each line is in a separate frag.  you generally can't
subtract labels in different frags (one of the frags might be something like
.align) until final placement, so we punt when evaluating the size expression. 
you could a) rewrite gas listing code from scratch to not use frags, b) look
back thru some frags when evaluating expressions
<bje> It seems like a pretty obscure corner case.
<alanm> yes, but people do keep running into the problem, even with listings
disabled.  eg. you might need a new frag simply because memory allocated for old
one runs out.  in that case the two frags have a fixed relationship wrt start
address, so you could subtract a label in one frag from a label in the other. 
not doing so breaks anything that depends on being able to evaluate such an
expression early.  conditional assembly, .org/.space, relax...