[Bug inline-asm/88952] New: [powerpc] asm input from C expression with type larger than GPRs loads wrong value

2019-01-21 Thread christopher.leonard at abaco dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88952

Bug ID: 88952
   Summary: [powerpc] asm input from C expression with type larger
than GPRs loads wrong value
   Product: gcc
   Version: 4.2.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: inline-asm
  Assignee: unassigned at gcc dot gnu.org
  Reporter: christopher.leonard at abaco dot com
  Target Milestone: ---

When giving a C expression as input to an extended asm statement the wrong
value is loaded if the type happens to be 64-bit (with 32-bit powerpc target).
Happens regardless of optimization level, use of 'volatile'. Also happens in
compiler explorer with GCC 4.8.5 <https://godbolt.org/z/hZAEEy>.

This subtle behavior is not too hard to track down but will probably defy the
expectations of the programmer, and could be introduced into a program with
seemingly innocuous changes that result in the overall expression type being
larger. I assume this is a bug and not the intention of the input operand
feature. If this is the intended functionality I would suggest adding a warning
for this situation.

Source "ex.c":
void bad_asm(void)
{
asm volatile ("stw %0, 50(0)" : :"r"(20ull));
}

Build command:
/opt/eldk/4.2/usr/ppc-linux/bin/gcc -mregnames -O3 -c -o ex.o ex.c

Disassembly:
ex.o: file format elf32-powerpc

Disassembly of section .text:

 :
   0:   39 20 00 00 li  r9,0
   4:   39 40 00 14 li  r10,20
   8:   91 20 00 32 stw r9,50(0)
   c:   4e 80 00 20 blr

Output of gcc -v:
Reading specs from
/opt/eldk/4.2/usr/bin/../lib/gcc/powerpc-linux/4.2.2/specs
Target: powerpc-linux
Configured with:
/opt/eldk/build/ppc-2008-04-01/work/usr/src/denx/BUILD/crosstool-0.43/build/gcc-4.2.2-glibc-20070515T2025-eldk/powerpc-linux/gcc-4.2.2/configure
--target=powerpc-linux --host=i686-host_pc-linux-gnu
--prefix=/var/tmp/eldk.UZpAG7/usr/crosstool/gcc-4.2.2-glibc-20070515T2025-eldk/powerpc-linux
--disable-hosted-libstdcxx
--with-headers=/var/tmp/eldk.UZpAG7/usr/crosstool/gcc-4.2.2-glibc-20070515T2025-eldk/powerpc-linux/powerpc-linux/include
--with-local-prefix=/var/tmp/eldk.UZpAG7/usr/crosstool/gcc-4.2.2-glibc-20070515T2025-eldk/powerpc-linux/powerpc-linux
--disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit
--enable-languages=c,c++,java --enable-shared --enable-c99 --enable-long-long
--without-x
Thread model: posix
gcc version 4.2.2

[Bug inline-asm/88952] [powerpc] asm input from C expression with type larger than GPRs loads wrong value

2019-01-21 Thread christopher.leonard at abaco dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88952

--- Comment #2 from Christopher Leonard  
---
Surely then in the example if r9 is loaded with high and r10 with low then %0
should be r10, not r9?

[Bug inline-asm/88952] [powerpc] asm input from C expression with type larger than GPRs loads wrong value

2019-01-21 Thread christopher.leonard at abaco dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88952

--- Comment #3 from Christopher Leonard  
---
I understand it has to split it, the problem is that %0 defaults to the
register holding the most-significant part of the integer. Is this really the
desired behavior?

[Bug target/88952] The asm operator modifiers for rs6000 should be documented like they are for x86

2019-01-22 Thread christopher.leonard at abaco dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88952

--- Comment #5 from Christopher Leonard  
---
Is the order at least consistant with x86-32? i.e. if you give a 64-bit input
operand to inline assembly the order is hi:lo? I'm worried this is a bizarre
convention imposed on high endian architectures.

[Bug target/88952] The asm operator modifiers for rs6000 should be documented like they are for x86

2019-01-22 Thread christopher.leonard at abaco dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88952

--- Comment #9 from Christopher Leonard  
---
(In reply to Andrew Pinski from comment #6)
> Yes the order is always hi:lo (reg:reg+1) on all targets I know of

This is definitely not the natural choice (on any platform: I agree, endianness
is irrelevant here) so I would recommend documenting this as well, and
potentially recommending in the docs to explicitly cast e.g. a parameter for a
function-style macro used as an input operand expression for inline asm, (%L0
is no help when the size is unknown, it seems to select the "next" register
when you give a 32-bit type, which isn't even loaded with a value in the
generated PPC assembly).

This is how the code messed up for me, I wrote a macro function to generate
MTSPR instructions for a given SPR and load value (this is needed since the SPR
number used in MTSPR is immediate, there is not alternative where you can take
the SPR from a register). One of the constants I used in the calculation of an
SPR's load value became a 64-bit type in a later code change, making the input
operand 64-bit instead of 32-bit, breaking my code.

[Bug target/88952] The asm operator modifiers for rs6000 should be documented like they are for x86

2019-01-22 Thread christopher.leonard at abaco dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88952

--- Comment #10 from Christopher Leonard  
---
Getting contradictory statements now:
>reg:reg+1 maps to lo:hi on x86.
>On x86, we don't allow register pairs in asm at all.

Not allowing, or printing a warning, is much better behavior than what I have
been getting on PPC.

[Bug target/88952] The asm operator modifiers for rs6000 should be documented like they are for x86

2019-06-17 Thread christopher.leonard at abaco dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88952

--- Comment #13 from Christopher Leonard  
---
(In reply to Segher Boessenkool from comment #12)
> the oldest GCC still supported is GCC 7.

Apologies if it was not clear, but I am just reporting the issue for posterity
and it was not easy for me to check on a newer version at the time.

If you are wondering why people use old versions of GCC, my usecase is working
on a codebase where consistent output is desirable over new features or
bugfixes, going back to when 4.x was new.