Illegal subtraction in tmp-dive_1.s

Torbjorn Granlund tg at gmplib.org
Thu Apr 16 13:38:25 CEST 2009


Marc Glisse <marc.glisse at normalesup.org> writes:

  On Wed, 15 Apr 2009, Dennis Clarke wrote:
  
  > I hit this repeatedly on Solaris x86.
  >
  > Assembler:
  >        "tmp-dive_1.s", line 292 : Illegal subtraction in ... ".DOT-0 -
  > __gmp_binvert_limb_table"
  > cc: assembler failed for tmp-dive_1.s
  
  Funny, on linux x86_64 with Sun Studio I also got an Illegal
  subtraction, but a different one: the Sun assembler refuses to compute
  differences of symbols in different sections, and
  x86_64/sqr_basecase.asm does just that. Moving "TEXT" before L(jmptab)
  in the 2 places where it occurs fixes it (I know gcc had a similar
  problem with bug 31713, fixed in 2007) and the result passes all
  tests.
  
I suspect you might get a performance degradation by putting the jump
table in the text segment, at least if you put it where instruction
fetching will occur.  This can happen since x86 processors typically do
not allow caching in both instruction L1 cache and data L2 cache, so
reading from the table with a load, will knock the entire cache line
from the instruction cache, and fetching instructions in the
neighbourhood will knock the table from the data cache.

Aligning the table start and padding its end to a cache line boundary
might help, but instruction prefetch might mean one needs to pad by more
than a cache line.


I don't know if the 64-bit ELF ABI actually allows us to subtract
symbols from different sections.  Anybody here knows?

If we're in breach of the ABI, or else we want to support a buggy
Solaris assembler/linker, we could enable the alternative code in
mpn/x86_64/sqr_basecase.asm, see the m4 "ifelse".  The alternative code
is probably a bit slower, since it is one instruction longer.  But it
might be possible to come up with a better sequence!

-- 
Torbjörn


More information about the gmp-discuss mailing list