typeof and operands in named address spaces

Uros Bizjak ubizjak@gmail.com
Thu Nov 5 10:33:26 GMT 2020

On Thu, Nov 5, 2020 at 10:36 AM Alexander Monakov <amonakov@ispras.ru> wrote:
> On Thu, 5 Nov 2020, Uros Bizjak via Gcc wrote:
> > > Looks like writing
> > >
> > >     typeof((typeof(_var))0) tmp__;
> > >
> > > makes it work.  Assumes there's a literal zero for the type of course.
> >
> > This is very limiting assumption, which already breaks for the following test:
> To elaborate Richard's idea, you need a way to decay lvalue to rvalue inside
> the typeof to strip the address space; if you need the macro to work for
> more types than just scalar types, the following expression may be useful:
>   typeof(0?(_var):(_var))
> (though there's a bug: +(_var) should also suffice for scalar types, but
>  somehow GCC keeps the address space on the resulting rvalue)
> But I wonder if you actually need this at all:
> > > works around the warning.  I think the wording you cite
> > > suggests (uintptr_t) &y here, not sure if there's a reliable
> > > way to get the lea with just a uintptr_t operand though.
> >
> > No, because we have to use the "m" constraint for the LEA. We get the
> > following error:
> What is the usecase for stripping the address space for asm operands?

Please see the end of [2], where the offset to <mem> is passed in %rsi
to the call to this_cpu_cmpxchg16b_emu. this_cpu_cmpxchg16b_emu
implements access with PER_CPU_VAR((%rsi)), which expands to
%gs:(%rsi), so it is the same as %gs:<mem> in cmpxchg16b alternative.
The offset is loaded by lea <mem>, %rsi to %rsi reg.

> From reading the patch I understand the kernel wants to pass qualified
> lvalues to inline assembly to get
>   lea <reg>, %fs:<mem>

No, this will emit an assembler warning that "segment override on
'lea' is ineffectual".


> LEA without the %fs will produce the offset within the segment, which
> you can obtain simply by casting the pointer to intptr_t in the first place.

> Alexander

More information about the Gcc mailing list