Bug 71216 - [4.9/5/6/7 Regression] Incorrect PPC assembly due to inserted .machine pseudo-op
Summary: [4.9/5/6/7 Regression] Incorrect PPC assembly due to inserted .machine pseudo-op
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 6.1.0
: P3 normal
Target Milestone: 4.9.4
Assignee: Segher Boessenkool
URL:
Keywords: wrong-code
: 78764 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-05-20 23:51 UTC by Josh Birnbaum
Modified: 2016-12-28 21:56 UTC (History)
1 user (show)

See Also:
Host:
Target: powerpc*-*-*
Build:
Known to work: 4.7.2, 4.9.1
Known to fail: 4.9.4, 5.1.0, 6.1.0, 7.0
Last reconfirmed: 2016-07-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Josh Birnbaum 2016-05-20 23:51:51 UTC
This report concerns rs6000_file_start() in config/rs6000/rs6000.c as modified by r219854

I'm working with the PowerPC 405 but I believe this affects a number of different chips.

GCC version info:
Target: powerpc-softfloat-linux
Configured with: ../gcc-6.1.0/configure --prefix=/toolchains/gcc-6.1.0-powerpc --build=i386-pc-linux-gnu --host=i386-pc-linux-gnu --target=powerpc-softfloat-linux --enable-languages=c,c++ --disable-nls --without-headers --disable-__cxa_atexit
Thread model: posix
gcc version 6.1.0 (GCC)

Simple C file used for testing:
int main ()
{
    unsigned tcr = 5;
           __asm__ volatile (
                "       mttcr   %0  \n"
                : /* no output */
                : "r"( tcr )
                );


    return 0;
}

Compiled using powerpc-softfloat-linux-gcc -mcpu=405 -mregnames -nostdlib -nodefaultlibs filename.c

objdump -d yields:
a.out:     file format elf32-powerpc


Disassembly of section .text:

10000074 <main>:
10000074:       94 21 ff e0     stwu    r1,-32(r1)
10000078:       93 e1 00 1c     stw     r31,28(r1)
1000007c:       7c 3f 0b 78     mr      r31,r1
10000080:       39 20 00 05     li      r9,5
10000084:       91 3f 00 08     stw     r9,8(r31)
10000088:       81 3f 00 08     lwz     r9,8(r31)
1000008c:       7d 3a f3 a6     mtspr   340,r9
10000090:       39 20 00 00     li      r9,0
10000094:       7d 23 4b 78     mr      r3,r9
10000098:       39 7f 00 20     addi    r11,r31,32
1000009c:       83 eb ff fc     lwz     r31,-4(r11)
100000a0:       7d 61 5b 78     mr      r1,r11
100000a4:       4e 80 00 20     blr

The "mtspr 340" part should be "mtspr 986" since the PowerPC 405 does not use the PowerPC Book E SPRN register numbers.

Using -save-temps I see the following assembly
        .file   "filename.c"
        .machine ppc
        .section        ".text"
        .align 2
        .globl main
        .type   main, @function
main:
        stwu 1,-32(1)
        stw 31,28(1)
        mr 31,1
        li 9,5
        stw 9,8(31)
        lwz 9,8(31)
#APP
 # 4 "filename.c" 1
               mttcr   9

 # 0 "" 2
#NO_APP
        li 9,0
        mr 3,9
        addi 11,31,32
        lwz 31,-4(11)
        mr 1,11
        blr
        .size   main, .-main
        .ident  "GCC: (GNU) 6.1.0"
        .section        .note.GNU-stack,"",@progbits

Note the ".machine ppc" part which overrides the parameters provided at the as command line.  In this case using "gcc -v" I saw:
powerpc-softfloat-linux/bin/as -v -m405 -many -mbig -o filename.o filename.s

So instead of -m405 the assember uses the setting of -mppc.  Per https://sourceware.org/binutils/docs/as/PowerPC_002dOpts.html#PowerPC_002dOpts this is PowerPC 603/604 assembly and not the requested PowerPC 403/405 assembly.

It appears this would happen for a number of the -m options, since the code in rs6000.c has .machine ppc as the default if none of the powerN or ppc64 selections apply.

Searching the Internet for related info on this issue for PowerPC 4xx I did find a related patch: https://github.com/sba1/adtools/blob/master/gcc/5/patches/0003-Disable-.machine-directive-generation.patch
Comment 1 Segher Boessenkool 2016-07-18 11:00:50 UTC
Confirmed.

Instead of disabling the current code that generates .machine, it would
work better to extend that code to handle more CPUs.  ".machine ppc"
works fine for all instructions GCC generates itself, but not for asm
code, as you found out.

As a workaround, you can code the desired SPR number manually.
Comment 2 Segher Boessenkool 2016-07-22 13:08:52 UTC
Author: segher
Date: Fri Jul 22 13:08:19 2016
New Revision: 238639

URL: https://gcc.gnu.org/viewcvs?rev=238639&root=gcc&view=rev
Log:
Subject: [PATCH] rs6000: Fix logic for when to emit .machine (PR71216)

The current logic determining whether to use .machine in the generated
asm code puts it there if the compiler is not configured with a default
target cpu, _or_ no -mcpu= was given on the command line.  It should
be "and" instead.


	PR target/71216
	* config/rs6000/rs6000.c (rs6000_file_start): Fix condition for
	when to emit a ".machine" pseudo-op.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/rs6000/rs6000.c
Comment 3 Segher Boessenkool 2016-07-27 16:12:37 UTC
Author: segher
Date: Wed Jul 27 16:12:05 2016
New Revision: 238788

URL: https://gcc.gnu.org/viewcvs?rev=238788&root=gcc&view=rev
Log:
rs6000: Fix logic for when to emit .machine (PR71216)

The current logic determining whether to use .machine in the generated
asm code puts it there if the compiler is not configured with a default
target cpu, _or_ no -mcpu= was given on the command line.  It should
be "and" instead.


	PR target/71216
	* config/rs6000/rs6000.c (rs6000_file_start): Fix condition for
	when to emit a ".machine" pseudo-op.

Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/config/rs6000/rs6000.c
Comment 4 Segher Boessenkool 2016-07-27 16:14:44 UTC
Author: segher
Date: Wed Jul 27 16:14:12 2016
New Revision: 238789

URL: https://gcc.gnu.org/viewcvs?rev=238789&root=gcc&view=rev
Log:
rs6000: Fix logic for when to emit .machine (PR71216)

The current logic determining whether to use .machine in the generated
asm code puts it there if the compiler is not configured with a default
target cpu, _or_ no -mcpu= was given on the command line.  It should
be "and" instead.


	PR target/71216
	* config/rs6000/rs6000.c (rs6000_file_start): Fix condition for
	when to emit a ".machine" pseudo-op.

Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/config/rs6000/rs6000.c
Comment 5 Segher Boessenkool 2016-07-27 16:18:16 UTC
Fixed on 5 and later, closing.
Comment 6 Segher Boessenkool 2016-12-15 22:08:21 UTC
*** Bug 78764 has been marked as a duplicate of this bug. ***
Comment 7 Rin Okuyama 2016-12-16 10:07:19 UTC
I'm the submitter of Bug 78764. I confirmed that my problem has been
resolved on gcc-5-branch. Let me thank you again for fixing it.

However, I have a question on this fix. How about the case where
"-Wa,-mXXX" option is given without "-mcpu=YYY" option specified?
The user expects that the assembler generates instructions for XXX,
and GCC itself does not take special care of the CPU type. However,
against this expectation, ".machine ppc" pseudo-op is output in
this case, which discards the CPU type specified by "-Wa,-mXXX".

This may sound pedantic to you. However, this is dangerous because
some special mnemonics in inline assembler codes can be misassembled.
In addition, for example, "-mcpu=e500" is forbidden whereas "-Wa,-me500"
is possible; the user cannot use instructions for e500 in inline
assembler codes.
Comment 8 Segher Boessenkool 2016-12-16 23:36:42 UTC
Hi Rin,

> However, I have a question on this fix. How about the case where
> "-Wa,-mXXX" option is given without "-mcpu=YYY" option specified?

That might or might not work; the user had better know what he is
doing if he uses an assembler option.

> This may sound pedantic to you. However, this is dangerous because
> some special mnemonics in inline assembler codes can be misassembled.
> In addition, for example, "-mcpu=e500" is forbidden whereas "-Wa,-me500"
> is possible; the user cannot use instructions for e500 in inline
> assembler codes.

GCC does not support -me500, right.  You need to configure your compiler
for a powerpc-*-eabispe* target as far as I know (I'm no expert on this).
Comment 9 Rin Okuyama 2016-12-18 03:29:09 UTC
Hi Segher,

Thank you for your kind reply. I committed your fix to NetBSD's local
tree of GCC 5.4.

> > However, I have a question on this fix. How about the case where
> > "-Wa,-mXXX" option is given without "-mcpu=YYY" option specified?
> 
> That might or might not work; the user had better know what he is
> doing if he uses an assembler option.

Hmm, I understand. Is this documented explicitly anywhere?

> > This may sound pedantic to you. However, this is dangerous because
> > some special mnemonics in inline assembler codes can be misassembled.
> > In addition, for example, "-mcpu=e500" is forbidden whereas "-Wa,-me500"
> > is possible; the user cannot use instructions for e500 in inline
> > assembler codes.
> 
> GCC does not support -me500, right.  You need to configure your compiler
> for a powerpc-*-eabispe* target as far as I know (I'm no expert on this).

We use -Wa,-me500 option to compile kernel on some machines. As they
share userland with other machines, we cannot configure GCC for a
powerpc-*-eabispe* target. Instead, I found a workaround to specify
-mcpu=powerpc option. It passes -mppc option to assembler, but as it
is preceding to -me500, the latter is prior to the former.
Comment 10 Segher Boessenkool 2016-12-22 19:15:28 UTC
(In reply to Rin Okuyama from comment #9)
> > > However, I have a question on this fix. How about the case where
> > > "-Wa,-mXXX" option is given without "-mcpu=YYY" option specified?
> > 
> > That might or might not work; the user had better know what he is
> > doing if he uses an assembler option.
> 
> Hmm, I understand. Is this documented explicitly anywhere?

Not in so many words I think, no.

> > GCC does not support -me500, right.  You need to configure your compiler
> > for a powerpc-*-eabispe* target as far as I know (I'm no expert on this).
> 
> We use -Wa,-me500 option to compile kernel on some machines. As they
> share userland with other machines, we cannot configure GCC for a
> powerpc-*-eabispe* target. Instead, I found a workaround to specify
> -mcpu=powerpc option. It passes -mppc option to assembler, but as it
> is preceding to -me500, the latter is prior to the former.

Maybe you could use -mcpu=e500mc or similar?  Or, GCC should probably
have a -mcpu=e500 option, but someone has to write the code for it.
Comment 11 Rin Okuyama 2016-12-28 21:56:29 UTC
Thank you for your response, and sorry for the late reply.

(In reply to Segher Boessenkool from comment #10)
> > > That might or might not work; the user had better know what he is
> > > doing if he uses an assembler option.
> > 
> > Hmm, I understand. Is this documented explicitly anywhere?
> 
> Not in so many words I think, no.

It would be nice if you could document it somewhere.

> > We use -Wa,-me500 option to compile kernel on some machines. As they
> > share userland with other machines, we cannot configure GCC for a
> > powerpc-*-eabispe* target. Instead, I found a workaround to specify
> > -mcpu=powerpc option. It passes -mppc option to assembler, but as it
> > is preceding to -me500, the latter is prior to the former.
> 
> Maybe you could use -mcpu=e500mc or similar?  Or, GCC should probably
> have a -mcpu=e500 option, but someone has to write the code for it.

Yeah, I hope so. But that would be another problem.

Let me thanks again for your kind support!