Bug 4572

Summary: division doesn't work on solaris/x86
Product: binutils Reporter: R. Clint Whaley <whaley>
Component: gasAssignee: unassigned
Status: RESOLVED FIXED    
Severity: normal CC: bug-binutils
Priority: P2    
Version: 2.17   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: Make GAS with a Solaris target treat '/' as it does for other *nixes

Description R. Clint Whaley 2007-05-31 14:09:04 UTC
Hi,

Not sure if this is a bug, but the assembler works oddly on solaris x86 as
opposed to x86 on (windows,OSX,Linux,*BSD).  Essentially, it can't take constant
expressions that include division.  I am running on an opteron running solaris,
and it can't assemble:
>cinna>cat tst.s
> movq $20/10, %rax
>cinna>/usr/local/binutils-2.16.1/x86_64-SunOS-gcc-3.4.2-sun/bin/as --64 -v >tst.s
>GNU assembler version 2.16.1 (i386-pc-solaris2.10) using BFD version 2.16.1
>tst.s: Assembler messages:
>tst.s:1: Error: suffix or operands invalid for `movq'

But it works fine on any other OS.  If this is expected behavior for sparc,
what's the reason, and is there any workaround?  If it is not expected behavior,
any ideas?  I support a large libary with many lines like this in it, and so far
this keeps me from porting to solaris/x86, even thouth my assembler works on the
 other x86 platforms.

Thanks,
Clint
Comment 1 R. Clint Whaley 2007-05-31 18:01:22 UTC
OK, I have established that the problem is that '/' is a comment character under
solaris/x86.  The Sun assembly ref manual states that \/ should work to perform
division in expressions, but this does not work for gnu as.  Any idea how to get
gas to do division in an integer expression?

Thanks,
Clint
Comment 2 Alan Modra 2007-06-01 01:52:55 UTC
You will need to modify app.c.
Comment 3 R. Clint Whaley 2007-06-01 02:44:01 UTC
I can modify the assembly source only by removing functionality.  In the
original code, it is a cpp macro defined to an integer constant that is being
passed in and being divided by known constant.  Without being able to do this, I
have to switch a compile-time division to a run-time one, which means a mov
becomes a long multicycle operation.  

You are saying there is no way to do division in integer expressions with gas on
solaris, even though it works on all other OSes?  Isn't that less than ideal?

Thanks,
Clint
Comment 4 Nick Clifton 2007-06-05 12:15:53 UTC
Subject: Re:  division doesn't work on solaris/x86

Hi Clint,

> You are saying there is no way to do division in integer expressions with gas on
> solaris, even though it works on all other OSes?  Isn't that less than ideal?

Actually Alan was saying that you should look at the assembler source 
file gas/app.c and see how you can modify it to interpret "\/" as a 
division operator and not a comment.

Cheers
   Nick


Comment 5 Michael Abshoff 2008-07-14 17:52:51 UTC
(In reply to comment #4)
> Subject: Re:  division doesn't work on solaris/x86
> 
> Hi Clint,

[My first journey into the world of binutils, so please be gentle :)]

Hi Clint, Alan, Nick,

> > You are saying there is no way to do division in integer expressions with gas on
> > solaris, even though it works on all other OSes?  Isn't that less than ideal?
> 
> Actually Alan was saying that you should look at the assembler source 
> file gas/app.c and see how you can modify it to interpret "\/" as a 
> division operator and not a comment.
> 
> Cheers
>    Nick
> 

I hit the problem Clint reported when building his project (ATLAS 3.8.1+Errata
applied specifically) on Solaris 10/Intel with compiled from vanilla sources
binutils 2.18. The solution is exposed when looking at gas/config/tc-i386.c: 

[quote]
#if (defined (TE_I386AIX)                               \
     || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \
         && !defined (TE_GNU)                           \
         && !defined (TE_LINUX)                         \
         && !defined (TE_NETWARE)                       \
         && !defined (TE_FreeBSD)                       \
         && !defined (TE_NetBSD)))
/* This array holds the chars that always start a comment.  If the
   pre-processor is disabled, these aren't very useful.  The option
   --divide will remove '/' from this list.  */
const char *i386_comment_chars = "#/"; [Remove the "/" here ]
#define SVR4_COMMENT_CHARS 1
#define PREFIX_SEPARATOR '\\'

#else
const char *i386_comment_chars = "#";
#define PREFIX_SEPARATOR '/'
#endif
[end quote]

There are two solutions:

 a) Brute force, i.e. remove "/" as indicated above

or

 b) add '-Wa,--divide' to the CFLAGS of ATLAS as suggested by the comments in
the source code

(a) worked on my Solaris 10 box, i.e. it build ATLAS and the rest of Sage, but
(b) seems like a much better solution since most people don't build their custom
binutils ;). I have not tried it yet, but on Solaris 10 on Intel (b) ought to
work universally since Sun's version of gas is from binutils 2.15 and the issue
you hit was allegedly introduced between 2.13 and 2.15 - see

http://osdir.com/ml/gnu.binutils.bugs/2005-02/msg00054.html

for that statement I have not verified. I attempted to build binutils 2.13 and
2.14 on Solaris 10 and it did not work, so this workaround (b) ought to work on
all Intel Solaris 10 boxen. Since I could not get any gcc to build using Sun's
as it also seems pretty save to me, but caution ought to be applied.

Clint: I will file a bug report against ATLAS in case you do not respond to this
ticket in the next couple days.

Cheers,

Michael
Comment 6 Alex Viskovatoff 2009-07-31 15:39:14 UTC
Created attachment 4102 [details]
Make GAS with a Solaris target treat '/' as it does for other *nixes

From the above comments it's fairly clear that the reason this "bug" exists is
that the Sus x86 Assembly Language Reference Manual states that '/' should be
treated as starting comments. I would like to suggest that requiring GAS to
adhere to that specification for Solaris targets is to misunderstand the role
that GAS plays in the Solaris world. People who run Solaris who use GAS do not
use it to assemble code that was written for the Sun assembler. They use it in
the process of porting code that was written for the GNU assembler, typically
with Linux targets, to Solaris. Making the default behavior of GAS with a
Solaris target to treat '/' as starting a comment makes porting software from
GNU/Linux to Solaris more difficult and cumbersome.

I propose changing the default behavior of GAS with a Solaris target when it
comes to '/' to be the same as it is for Linux and other Unixes such as FreeBSD
and NetBSD. I have attached a patch, called svr4-comment.diff, which changes
the default behavior of GAS for Solaris to conform to that of other *nix
targets, and adds an option, called "svr4-comments", which changes the behavior
back to the present one. This patch is modeled after the code for the
"--divide" option. I've tested the patch under the current development release
of OpenSolaris, snv_118, on an X64 system.

The issue of GAS producing errors for a Solaris target when '/' is used to
indicate division comes up repeatedly in forums and mailing lists. When the
reason for this behavior is finally discovered, it is difficult to get
maintainers of the code in question to accept a Solaris-specific patch to get
around it, apparently because maintainers find that the need for such a patch
is just too bizarre. I've floated this proposal to change the default behavior
on the OpenSolaris.org forums, and the response was that making GAS for Solaris
targets adhere to the archaic Sun convention for comments as opposed to conform
to the rest of the *nix world is wrong. Also, it was felt that modifying any
existing code that is part of Solaris or OpenSolaris which uses '/' to indicate
comments and which is assembled using GAS instead of the Sun assembler (if
there is such code) to use the new proposed option would not be a significant
burden.

I hope the maintainers will look positively on this proposal. Its acceptance
would make life in the Solaris world easier.
Comment 7 H.J. Lu 2009-08-01 05:03:36 UTC
I suggest you add a new option to treate '/' as divide on Solaris.
Comment 8 Alex Viskovatoff 2009-08-01 17:13:51 UTC
Subject: Re:  division doesn't work on solaris/x86

hjl dot tools at gmail dot com wrote:
> ------- Additional Comments From hjl dot tools at gmail dot com  2009-08-01 05:03 -------
> I suggest you add a new option to treate '/' as divide on Solaris.

Such an option already exists. It's called "--divide", and it was 
mentioned in earlier comments, including my own.

The reason I am proposing my patch is that it doesn't make any sense for 
GAS to observe the Solaris assembler reference manual stipulation that 
slashes begin comments, because if someone is interested in writing or 
using code directed specifically at Solaris, he or she will use the Sun 
assembler, not GAS. The reason people in the Solaris world use GAS is to 
port GNU/Linux programs, and making the behavior with respect to slashes 
specified in the Solaris assembler reference manual the default, as 
opposed to the behavior under Linux, makes that more difficult.

The question is: are we going to have people porting software from 
GNU/Linux to Solaris endlessly patch code to make GAS behave for 
Solaris/X86 targets as it does for Linux targets? Or are we going to 
make a single patch to GAS with the functionality proposed here, solving 
this problem once and for all?

People in the OpenSolaris community, unless they do a fair amount of 
Googling, usually conclude that this behavior of GAS for Solaris/X86 
targets is a bug when they run into it. Those who look into the problem 
a little more thoroughly optimistically expect that this behavior will 
go away with some future version of Binutils.

Alex
Comment 9 R. Clint Whaley 2009-08-02 16:42:50 UTC
I think defaulting to the gnu ('/' means division) behavior is the right thing
as well.

Note that the present behavior does *not* match solaris, since \/ does not allow
division, as the solaris manual says it should.  Therefore, the present default
is nonstandard in every way, and it is difficult to see why it should be
retained over defaulting to at least one standard behavior, and defaulting to
Linux/x86 standard would certainly help other libraries to port (I reworked
every assembly file in ATLAS to work around this bug a couple of years ago).
Comment 10 H.J. Lu 2009-08-03 01:19:41 UTC
Gas is mainly for gcc. Assembler from Sun may not support the
new x86 instructions, like SSE4, AVX, .... You may have to use
gas with gcc.  It isn't a good idea to make gas different from
the native assembler on this by default.
Comment 11 R. Clint Whaley 2009-08-03 16:39:44 UTC
(In reply to comment #10)
> Gas is mainly for gcc. Assembler from Sun may not support the
> new x86 instructions, like SSE4, AVX, .... You may have to use
> gas with gcc.  It isn't a good idea to make gas different from
> the native assembler on this by default.

OK, then why doesn't \/ work?  This would be the same as the native assembler. 
I believe gcc's present default of having / be the comment character, but not
allowing \/ to work means that it fails to act like either the solaris as *or*
itself on linux/x86.

I believe working like linux/x86 would ease porting to solaris/x86, which is
important since this is likely to remain a niche x86 platform, but at least
acting like the solaris as would be coherent . . .

Thanks,
Clint
Comment 12 H.J. Lu 2009-08-04 22:57:35 UTC
A patch is posted at

http://sourceware.org/ml/binutils/2009-08/msg00048.html
Comment 13 Sourceware Commits 2020-07-20 06:57:52 UTC
The master branch has been updated by Jan Beulich <jbeulich@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=750e4bf70f2caab39dc5d0a1b2d26c9ca1fbd909

commit 750e4bf70f2caab39dc5d0a1b2d26c9ca1fbd909
Author: Jan Beulich <jbeulich@suse.com>
Date:   Mon Jul 20 08:56:23 2020 +0200

    gas: generalize comment character escaping recognition
    
    PR gas/4572
    
    Generalize what ab1fadc6b2f0 ("PR22714, Assembler preprocessor loses
    track of \@") did to always honor escaped comment chars. Use this then
    to support escaped /, %, and * operators on x86, when / is a comment
    char (to match the Sun assembler's behavior).
Comment 14 Sourceware Commits 2020-07-20 06:57:57 UTC
The master branch has been updated by Jan Beulich <jbeulich@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b3983e5f53caad175563f8c842f2ab2a1277c2bc

commit b3983e5f53caad175563f8c842f2ab2a1277c2bc
Author: Jan Beulich <jbeulich@suse.com>
Date:   Mon Jul 20 08:57:18 2020 +0200

    x86: handle SVR4 escaped binary operators
    
    PR gas/4572
    
    When / is a comment character, its use as binary "divide" operator needs
    escaping by a backslash. Besides the scrubber needing to support this
    (addressed in an earlier change), there are also a few provisions needed
    in target specific operator handling.
    
    As the spec calls for % and * to also be escaped because of being
    "overloaded", also recognize these, despite the overloading there not
    really preventing their use as operators in most (%) or all (*) cases,
    given the way how the rest of the assembler works.
    
    To bring source and testsuite in line, also drop the TE_I386AIX part of
    the respective conditional, as i?86-*-aix* support had been removed a
    while ago.
Comment 15 Alan Modra 2021-06-03 12:06:29 UTC
Looks like this one should have been closed last year