[lkml]   [2020]   [Jun]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
SubjectRe: [PATCH v4 1/2] powerpc/uaccess: Implement unsafe_put_user() using 'asm goto'
On Thu, Jun 11, 2020 at 4:53 PM Segher Boessenkool
<> wrote:
> On Thu, Jun 11, 2020 at 03:43:55PM -0700, Nick Desaulniers wrote:
> > Segher, Cristophe, I suspect Clang is missing support for the %L and %U
> > output templates [1].
> The arch/powerpc kernel first used the %U output modifier in 0c176fa80fdf
> (from 2016), and %L in b8b572e1015f (2008). include/asm-ppc (and ppc64)
> have had %U since 2005 (1da177e4c3f4), and %L as well (0c541b4406a6).

Thanks for all the references. So it looks like we should have failed
sooner, if we didn't support those. Hmm...

> > Can you please point me to documentation/unit tests/source for
> > these so that I can figure out what they should be doing, and look into
> > implementing them in Clang?
> The PowerPC part of
> (sorry, no anchor) documents %U.

I thought those were constraints, not output templates? Oh,
The asm statement must also use %U<opno> as a placeholder for the
“update” flag in the corresponding load or store instruction.
got it.

> Traditionally the source code is the documentation for this. The code
> here starts with the comment
> /* Write second word of DImode or DFmode reference. Works on register
> or non-indexed memory only. */
> (which is very out-of-date itself, it works fine for e.g. TImode as well,
> but alas).
> Unit tests are completely unsuitable for most compiler things like this.

What? No, surely one may write tests for output operands. Grepping
for `%L` in gcc/ was less fun than I was hoping.

> The source code is gcc/config/rs6000/rs6000.c, easiest is to search for
> 'L' (with those quotes). Function print_operand.
> HtH,

Yes, perfect, thank you so much! So it looks like LLVM does not yet
handle %L properly for memory operands.
It's neat to see how this is implemented in GCC (and how many aren't
implemented in LLVM, yikes :( ). For reference, this is implemented
in PPCAsmPrinter::PrintAsmOperand() and
PPCAsmPrinter::PrintAsmMemoryOperand() in
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp. GCC switches first on the
modifier characters, then the operand type. LLVM dispatches on operand
type, then modifier. When I was looking into LLVM's AsmPrinter class,
I was surprised to see it's basically an assembler that just has
complex logic to just do a bunch of prints, so it makes sense to see
that pattern in GCC literally calling printf. Not drastically
different than my first toy compiler
(looking back at that post now knowing what relocations are, I feel I
should probably add a note that that's a problem that's being solved
there. Didn't know it at the time).

Some things I don't understand from PPC parlance is the "mode"
(preinc, predec, premodify) and small data operands?

IIUC the bug report correctly, it looks like LLVM is failing for the
__put_user_asm2_goto case for -m32. A simple reproducer:

void foo(long long in, long long* out) {
asm volatile(
"stw%X1 %0, %1\n\t"
"stw%X1 %L0, %L1"
::"r"(in), "m"(*out));
prints (in GCC):
stw 3, 0(5)
stw 4, 4(5)
(first time looking at ppc assembler, seems constants and registers
are not as easy to distinguish, say "Get
used to it." LOL, ok).
so that's "store word from register 3 into dereference of register 5
plus 0, then store word from register 4 into dereference of register 5
plus 4?" Guessing the ppc32 abi is ILP32 putting long long's into two
separate registers?
Seems easy to implement in LLVM (short of those modes/small data operands).
~Nick Desaulniers

 \ /
  Last update: 2020-06-12 23:33    [W:0.075 / U:1.012 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site