Message ID | BANLkTik+E3O5uXnJRUWdSefzP3iFSAccnw@mail.gmail.com |
---|---|
State | New |
Headers | show |
On 05/24/2011 07:28 PM, H.J. Lu wrote: > This patch implements pause intrinsic suggested by Andi. OK > for trunk? What does "full memory barrier" here mean? +@table @code +@item void __builtin_ia32_pause (void) +Generates the @code{pause} machine instruction with full memory barrier. +@end table There a memory clobber, but no barrier instruction AFAICS. The doc needs to explain it a bit better. Andrew.
On Wed, May 25, 2011 at 12:26 PM, Andrew Haley <aph@redhat.com> wrote: > On 05/24/2011 07:28 PM, H.J. Lu wrote: > >> This patch implements pause intrinsic suggested by Andi. OK >> for trunk? > > What does "full memory barrier" here mean? > > +@table @code > +@item void __builtin_ia32_pause (void) > +Generates the @code{pause} machine instruction with full memory barrier. > +@end table > > There a memory clobber, but no barrier instruction AFAICS. The > doc needs to explain it a bit better. The name also sounds odd to me (reminds me of Fortran PAUSE ...). Richard. > Andrew. >
On Wed, May 25, 2011 at 3:26 AM, Andrew Haley <aph@redhat.com> wrote: > On 05/24/2011 07:28 PM, H.J. Lu wrote: > >> This patch implements pause intrinsic suggested by Andi. OK >> for trunk? > > What does "full memory barrier" here mean? > > +@table @code > +@item void __builtin_ia32_pause (void) > +Generates the @code{pause} machine instruction with full memory barrier. > +@end table > > There a memory clobber, but no barrier instruction AFAICS. The > doc needs to explain it a bit better. > There are read/load memory barrier, write/store memory barrier and full/general memory barrier. You can find them at http://www.kernel.org/doc/Documentation/memory-barriers.txt Should I include a pointer to it?
On Wed, May 25, 2011 at 3:31 AM, Richard Guenther <richard.guenther@gmail.com> wrote: > On Wed, May 25, 2011 at 12:26 PM, Andrew Haley <aph@redhat.com> wrote: >> On 05/24/2011 07:28 PM, H.J. Lu wrote: >> >>> This patch implements pause intrinsic suggested by Andi. OK >>> for trunk? >> >> What does "full memory barrier" here mean? >> >> +@table @code >> +@item void __builtin_ia32_pause (void) >> +Generates the @code{pause} machine instruction with full memory barrier. >> +@end table >> >> There a memory clobber, but no barrier instruction AFAICS. The >> doc needs to explain it a bit better. > > The name also sounds odd to me (reminds me of Fortran PAUSE ...). > __builtin_ia32_pause is the C intrinsic for x86 machine instruction. I don't think people will get confused by its name.
On Tue, May 24, 2011 at 8:28 PM, H.J. Lu <hjl.tools@gmail.com> wrote: > This patch implements pause intrinsic suggested by Andi. OK > for trunk? > gcc/ > > 2011-05-24 H.J. Lu <hongjiu.lu@intel.com> > > * config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_PAUSE. > (bdesc_special_args): Add pause intrinsic. > > * config/i386/i386.md (UNSPEC_PAUSE): New. > (pause): Likewise. > (*pause): Likewise. > * config/i386/ia32intrin.h (__pause): Likewise. > > * doc/extend.texi (X86 Built-in Functions): Add documentation for > pause intrinsic. > > gcc/testsuite/ > > 2011-05-24 H.J. Lu <hongjiu.lu@intel.com> > > * gcc.target/i386/pause-1.c: New. OK. Thanks, Uros.
On 05/25/2011 01:34 PM, H.J. Lu wrote: > On Wed, May 25, 2011 at 3:26 AM, Andrew Haley <aph@redhat.com> wrote: >> On 05/24/2011 07:28 PM, H.J. Lu wrote: >> >>> This patch implements pause intrinsic suggested by Andi. OK >>> for trunk? >> >> What does "full memory barrier" here mean? >> >> +@table @code >> +@item void __builtin_ia32_pause (void) >> +Generates the @code{pause} machine instruction with full memory barrier. >> +@end table >> >> There a memory clobber, but no barrier instruction AFAICS. The >> doc needs to explain it a bit better. > > There are read/load memory barrier, write/store memory barrier and full/general > memory barrier. You can find them at > > http://www.kernel.org/doc/Documentation/memory-barriers.txt > > Should I include a pointer to it? No. I know perfectly well what memory barriers are. I'm not asking what "full memory barrier" means. What barrier instruction(s) does __builtin_ia32_pause() generate? All I see in the patch is "rep; nop". Is that really a full memory barrier? Andrew.
On Wed, May 25, 2011 at 7:36 AM, Andrew Haley <aph@redhat.com> wrote: > On 05/25/2011 01:34 PM, H.J. Lu wrote: >> On Wed, May 25, 2011 at 3:26 AM, Andrew Haley <aph@redhat.com> wrote: >>> On 05/24/2011 07:28 PM, H.J. Lu wrote: >>> >>>> This patch implements pause intrinsic suggested by Andi. OK >>>> for trunk? >>> >>> What does "full memory barrier" here mean? >>> >>> +@table @code >>> +@item void __builtin_ia32_pause (void) >>> +Generates the @code{pause} machine instruction with full memory barrier. >>> +@end table >>> >>> There a memory clobber, but no barrier instruction AFAICS. The >>> doc needs to explain it a bit better. >> >> There are read/load memory barrier, write/store memory barrier and full/general >> memory barrier. You can find them at >> >> http://www.kernel.org/doc/Documentation/memory-barriers.txt >> >> Should I include a pointer to it? > > No. I know perfectly well what memory barriers are. I'm not asking > what "full memory barrier" means. > > What barrier instruction(s) does __builtin_ia32_pause() generate? > All I see in the patch is "rep; nop". Is that really a full memory > barrier? > It is a full memory barrier in the sense that compiler won't move load/store across it. It is intended for kernel.
On Wed, May 25, 2011 at 4:47 PM, H.J. Lu <hjl.tools@gmail.com> wrote: > On Wed, May 25, 2011 at 7:36 AM, Andrew Haley <aph@redhat.com> wrote: >> On 05/25/2011 01:34 PM, H.J. Lu wrote: >>> On Wed, May 25, 2011 at 3:26 AM, Andrew Haley <aph@redhat.com> wrote: >>>> On 05/24/2011 07:28 PM, H.J. Lu wrote: >>>> >>>>> This patch implements pause intrinsic suggested by Andi. OK >>>>> for trunk? >>>> >>>> What does "full memory barrier" here mean? >>>> >>>> +@table @code >>>> +@item void __builtin_ia32_pause (void) >>>> +Generates the @code{pause} machine instruction with full memory barrier. >>>> +@end table >>>> >>>> There a memory clobber, but no barrier instruction AFAICS. The >>>> doc needs to explain it a bit better. >>> >>> There are read/load memory barrier, write/store memory barrier and full/general >>> memory barrier. You can find them at >>> >>> http://www.kernel.org/doc/Documentation/memory-barriers.txt >>> >>> Should I include a pointer to it? >> >> No. I know perfectly well what memory barriers are. I'm not asking >> what "full memory barrier" means. >> >> What barrier instruction(s) does __builtin_ia32_pause() generate? >> All I see in the patch is "rep; nop". Is that really a full memory >> barrier? >> > > It is a full memory barrier in the sense that compiler won't move > load/store across it. It is intended for kernel. There is no such thing if you include accesses to automatic variables. Richard. > -- > H.J. >
On 05/25/2011 03:47 PM, H.J. Lu wrote: > On Wed, May 25, 2011 at 7:36 AM, Andrew Haley <aph@redhat.com> wrote: >> On 05/25/2011 01:34 PM, H.J. Lu wrote: >>> On Wed, May 25, 2011 at 3:26 AM, Andrew Haley <aph@redhat.com> wrote: >>>> On 05/24/2011 07:28 PM, H.J. Lu wrote: >>>> >>>>> This patch implements pause intrinsic suggested by Andi. OK >>>>> for trunk? >>>> >>>> What does "full memory barrier" here mean? >>>> >>>> +@table @code >>>> +@item void __builtin_ia32_pause (void) >>>> +Generates the @code{pause} machine instruction with full memory barrier. >>>> +@end table >>>> >>>> There a memory clobber, but no barrier instruction AFAICS. The >>>> doc needs to explain it a bit better. >>> >>> There are read/load memory barrier, write/store memory barrier and full/general >>> memory barrier. You can find them at >>> >>> http://www.kernel.org/doc/Documentation/memory-barriers.txt >>> >>> Should I include a pointer to it? >> >> No. I know perfectly well what memory barriers are. I'm not asking >> what "full memory barrier" means. >> >> What barrier instruction(s) does __builtin_ia32_pause() generate? >> All I see in the patch is "rep; nop". Is that really a full memory >> barrier? > > It is a full memory barrier in the sense that compiler won't move > load/store across it. It is intended for kernel. Right, so it is, in fact, not a full memory barrier. I thought not. I's no more a full memory barrier than a simple asm volatile("") . The doc needs to explain that a bit better. Andrew.
On Wed, May 25, 2011 at 4:54 PM, Andrew Haley <aph@redhat.com> wrote: > On 05/25/2011 03:47 PM, H.J. Lu wrote: >> On Wed, May 25, 2011 at 7:36 AM, Andrew Haley <aph@redhat.com> wrote: >>> On 05/25/2011 01:34 PM, H.J. Lu wrote: >>>> On Wed, May 25, 2011 at 3:26 AM, Andrew Haley <aph@redhat.com> wrote: >>>>> On 05/24/2011 07:28 PM, H.J. Lu wrote: >>>>> >>>>>> This patch implements pause intrinsic suggested by Andi. OK >>>>>> for trunk? >>>>> >>>>> What does "full memory barrier" here mean? >>>>> >>>>> +@table @code >>>>> +@item void __builtin_ia32_pause (void) >>>>> +Generates the @code{pause} machine instruction with full memory barrier. >>>>> +@end table >>>>> >>>>> There a memory clobber, but no barrier instruction AFAICS. The >>>>> doc needs to explain it a bit better. >>>> >>>> There are read/load memory barrier, write/store memory barrier and full/general >>>> memory barrier. You can find them at >>>> >>>> http://www.kernel.org/doc/Documentation/memory-barriers.txt >>>> >>>> Should I include a pointer to it? >>> >>> No. I know perfectly well what memory barriers are. I'm not asking >>> what "full memory barrier" means. >>> >>> What barrier instruction(s) does __builtin_ia32_pause() generate? >>> All I see in the patch is "rep; nop". Is that really a full memory >>> barrier? >> >> It is a full memory barrier in the sense that compiler won't move >> load/store across it. It is intended for kernel. > > Right, so it is, in fact, not a full memory barrier. I thought not. > I's no more a full memory barrier than a simple asm volatile("") . > The doc needs to explain that a bit better. asm volatile ("" : : : "memory") in fact will work as a full memory barrier because we are very very lazy in disambiguating against asms (but that should change, at least a tiny bit). Function calls otoh are pretty well optimized. Richard. > Andrew. >
On 05/25/2011 03:57 PM, Richard Guenther wrote: > > asm volatile ("" : : : "memory") in fact will work as a full memory barrier How? You surely need MFENCE or somesuch, unless all you care about is a compiler barrier. That's what I think needs to be clarified. Andrew.
On Wed, May 25, 2011 at 5:09 PM, Andrew Haley <aph@redhat.com> wrote: > On 05/25/2011 03:57 PM, Richard Guenther wrote: >> >> asm volatile ("" : : : "memory") in fact will work as a full memory barrier > > How? You surely need MFENCE or somesuch, unless all you > care about is a compiler barrier. That's what I think needs > to be clarified. Well, yes, I'm talking about the compiler memory barrier. Richard. > Andrew. >
Hi, On Wed, 25 May 2011, Richard Guenther wrote: > >> asm volatile ("" : : : "memory") in fact will work as a full memory > >> barrier > > > > How? You surely need MFENCE or somesuch, unless all you care about is > > a compiler barrier. That's what I think needs to be clarified. > > Well, yes, I'm talking about the compiler memory barrier. Something that we conventionally call "optimization barrier" :) memory barrier has a fixed meaning which we shouldn't use in this case, it's confusing. Ciao, Michael.
On Wed, May 25, 2011 at 5:20 PM, Michael Matz <matz@suse.de> wrote: > Hi, > > On Wed, 25 May 2011, Richard Guenther wrote: > >> >> asm volatile ("" : : : "memory") in fact will work as a full memory >> >> barrier >> > >> > How? You surely need MFENCE or somesuch, unless all you care about is >> > a compiler barrier. That's what I think needs to be clarified. >> >> Well, yes, I'm talking about the compiler memory barrier. > > Something that we conventionally call "optimization barrier" :) memory > barrier has a fixed meaning which we shouldn't use in this case, it's > confusing. Sure ;) And to keep the info in a suitable thread what I'd like to improve here is to make us disambiguate memory loads/stores against asms that have no memory outputs/inputs. Richard.
On Wed, May 25, 2011 at 8:27 AM, Richard Guenther <richard.guenther@gmail.com> wrote: > On Wed, May 25, 2011 at 5:20 PM, Michael Matz <matz@suse.de> wrote: >> Hi, >> >> On Wed, 25 May 2011, Richard Guenther wrote: >> >>> >> asm volatile ("" : : : "memory") in fact will work as a full memory >>> >> barrier >>> > >>> > How? You surely need MFENCE or somesuch, unless all you care about is >>> > a compiler barrier. That's what I think needs to be clarified. >>> >>> Well, yes, I'm talking about the compiler memory barrier. >> >> Something that we conventionally call "optimization barrier" :) memory >> barrier has a fixed meaning which we shouldn't use in this case, it's >> confusing. > > Sure ;) > > And to keep the info in a suitable thread what I'd like to improve here > is to make us disambiguate memory loads/stores against asms that > have no memory outputs/inputs. > Please let me know how I should improve the document, Thanks.
On 05/25/2011 04:32 PM, H.J. Lu wrote: > On Wed, May 25, 2011 at 8:27 AM, Richard Guenther > <richard.guenther@gmail.com> wrote: >> On Wed, May 25, 2011 at 5:20 PM, Michael Matz <matz@suse.de> wrote: >>> Hi, >>> >>> On Wed, 25 May 2011, Richard Guenther wrote: >>> >>>>>> asm volatile ("" : : : "memory") in fact will work as a full memory >>>>>> barrier >>>>> >>>>> How? You surely need MFENCE or somesuch, unless all you care about is >>>>> a compiler barrier. That's what I think needs to be clarified. >>>> >>>> Well, yes, I'm talking about the compiler memory barrier. >>> >>> Something that we conventionally call "optimization barrier" :) memory >>> barrier has a fixed meaning which we shouldn't use in this case, it's >>> confusing. >> >> Sure ;) >> >> And to keep the info in a suitable thread what I'd like to improve here >> is to make us disambiguate memory loads/stores against asms that >> have no memory outputs/inputs. >> > > Please let me know how I should improve the document, "Compiler memory barrier" seems to be well-understood. I suggest +Generates the @code{pause} machine instruction with a compiler memory barrier. It's clear enough. Andrew.
On Wed, 25 May 2011 11:26:51 +0100 Andrew Haley <aph@redhat.com> wrote: > On 05/24/2011 07:28 PM, H.J. Lu wrote: > > > This patch implements pause intrinsic suggested by Andi. OK > > for trunk? > > What does "full memory barrier" here mean? > > +@table @code > +@item void __builtin_ia32_pause (void) > +Generates the @code{pause} machine instruction with full memory barrier. > +@end table > > There a memory clobber, but no barrier instruction AFAICS. The > doc needs to explain it a bit better. Perhaps the doc might explain why is it necessary to have a builtin for two independent roles: first, the full compiler memory barrier (which probably means to spill all the registers on the stack - definitely a task for a compiler); second, to "pause" the processor (which might also mean to flush or invalidate some data caches). In particular, I would naively imagine that we might have a more generic builtin for the compiler memory barrier (which probably could be independent of the particular ia32 target), and in that case which can't we just implement the pause ia32 builtin as builtin_compiler_barrier(); asm ("pause")? I find the above documentation too short and (being a non native English speaker) I would prefer it to be much longer. I am not able to suggest better phrasing (because I still did not entirely understood what that builtin_ia32_pause is useful or needed). And if there was a builtin_compiler_barrier () I would believe it can have a lot of other uses. Any generated C code which wants some introspection or some garbage collection write barrier might want it too! [perhaps even I might find later such thing useful in C code generated by MELT] Regards.
On Wed, May 25, 2011 at 12:17 PM, Basile Starynkevitch <basile@starynkevitch.net> wrote: > On Wed, 25 May 2011 11:26:51 +0100 > Andrew Haley <aph@redhat.com> wrote: > >> On 05/24/2011 07:28 PM, H.J. Lu wrote: >> >> > This patch implements pause intrinsic suggested by Andi. OK >> > for trunk? >> >> What does "full memory barrier" here mean? >> >> +@table @code >> +@item void __builtin_ia32_pause (void) >> +Generates the @code{pause} machine instruction with full memory barrier. >> +@end table >> >> There a memory clobber, but no barrier instruction AFAICS. The >> doc needs to explain it a bit better. > > Perhaps the doc might explain why is it necessary to have a builtin for > two independent roles: first, the full compiler memory barrier (which > probably means to spill all the registers on the stack - definitely a > task for a compiler); second, to "pause" the processor (which might > also mean to flush or invalidate some data caches). In particular, I > would naively imagine that we might have a more generic builtin for the > compiler memory barrier (which probably could be independent of the > particular ia32 target), and in that case which can't we just implement > the pause ia32 builtin as builtin_compiler_barrier(); asm ("pause")? > We may need builtin_compiler_barrier(); asm ("pause"); builtin_compiler_barrier();
On Wed, 25 May 2011 12:31:17 -0700 "H.J. Lu" <hjl.tools@gmail.com> wrote: > On Wed, May 25, 2011 at 12:17 PM, Basile Starynkevitch > <basile@starynkevitch.net> wrote: > > Perhaps the doc might explain why is it necessary to have a builtin for > > two independent roles: first, the full compiler memory barrier (which > > probably means to spill all the registers on the stack - definitely a > > task for a compiler); second, to "pause" the processor (which might > > also mean to flush or invalidate some data caches). In particular, I > > would naively imagine that we might have a more generic builtin for the > > compiler memory barrier (which probably could be independent of the > > particular ia32 target), and in that case which can't we just implement > > the pause ia32 builtin as builtin_compiler_barrier(); asm ("pause")? > > > > We may need > > builtin_compiler_barrier(); > asm ("pause"); > builtin_compiler_barrier(); I don't understand why the second builtin_compiler_barrier() after the asm ("pause") would be needed? Could you please explain why should we need it? My feeling was that after the first builtin_compiler_barrier () and hence after the asm ("pause") no register would contain valid data, and the compiler would have to reload from memory everything. So why do you think the second is needed??? Or perhaps I misunderstood completely all the issues!
On 25/05/11 20:17, Basile Starynkevitch wrote: > On Wed, 25 May 2011 11:26:51 +0100 > Andrew Haley <aph@redhat.com> wrote: > >> On 05/24/2011 07:28 PM, H.J. Lu wrote: >> >>> This patch implements pause intrinsic suggested by Andi. OK >>> for trunk? >> >> What does "full memory barrier" here mean? >> >> +@table @code >> +@item void __builtin_ia32_pause (void) >> +Generates the @code{pause} machine instruction with full memory barrier. >> +@end table >> >> There a memory clobber, but no barrier instruction AFAICS. The >> doc needs to explain it a bit better. > > Perhaps the doc might explain why is it necessary to have a builtin for > two independent roles: first, the full compiler memory barrier (which > probably means to spill all the registers on the stack No. It clobbers all of _memory_, which doesn't involve auto variables. I don't understand why __builtin_ia32_pause needs to have a barrier either. > - definitely a > task for a compiler); second, to "pause" the processor (which might > also mean to flush or invalidate some data caches). No, it doesn't. I posted exactly what pause does in an earlier mail. Andrew.
Basile Starynkevitch <basile@starynkevitch.net> writes: > > Perhaps the doc might explain why is it necessary to have a builtin for > two independent roles: first, the full compiler memory barrier (which > probably means to spill all the registers on the stack - definitely a > task for a compiler); second, to "pause" the processor (which might > also mean to flush or invalidate some data caches). In particular, I > would naively imagine that we might have a more generic builtin for the > compiler memory barrier (which probably could be independent of the > particular ia32 target), and in that case which can't we just implement > the pause ia32 builtin as builtin_compiler_barrier(); asm ("pause")? Because a pause() which can be freely moved around is pretty much useless. Think about it. And a memory barrier is the standard way to prevent moving around in relation to other code. You would always need to combine those too. -Andi
On Thu, 26 May 2011 09:12:06 -0700 Andi Kleen <andi@firstfloor.org> wrote: > Basile Starynkevitch <basile@starynkevitch.net> writes: > > > > Perhaps the doc might explain why is it necessary to have a builtin for > > two independent roles: first, the full compiler memory barrier (which > > probably means to spill all the registers on the stack - definitely a > > task for a compiler); second, to "pause" the processor (which might > > also mean to flush or invalidate some data caches). In particular, I > > would naively imagine that we might have a more generic builtin for the > > compiler memory barrier (which probably could be independent of the > > particular ia32 target), and in that case which can't we just implement > > the pause ia32 builtin as builtin_compiler_barrier(); asm ("pause")? > > Because a pause() which can be freely moved around is pretty much > useless. Think about it. And a memory barrier is the standard > way to prevent moving around in relation to other code. I thought that there is a syntax, perhaps volatile asm("pause"), which forbids the compiler to move an asm statement? Or is the "memory" thing? (I am not very used to GCC asm). Still, is there a way to ask GCC to spill all data from registers to memory, and to require GCC to consider all registers crappy and to reload them when needed? I would imagine that such a feature is useful, and most importantly, that it should not be specific to ia32! Regards.
gcc/ 2011-05-24 H.J. Lu <hongjiu.lu@intel.com> * config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_PAUSE. (bdesc_special_args): Add pause intrinsic. * config/i386/i386.md (UNSPEC_PAUSE): New. (pause): Likewise. (*pause): Likewise. * config/i386/ia32intrin.h (__pause): Likewise. * doc/extend.texi (X86 Built-in Functions): Add documentation for pause intrinsic. gcc/testsuite/ 2011-05-24 H.J. Lu <hongjiu.lu@intel.com> * gcc.target/i386/pause-1.c: New. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 854e376..174caa0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -23912,6 +23912,7 @@ enum ix86_builtins IX86_BUILTIN_CLFLUSH, IX86_BUILTIN_MFENCE, IX86_BUILTIN_LFENCE, + IX86_BUILTIN_PAUSE, IX86_BUILTIN_BSRSI, IX86_BUILTIN_BSRDI, @@ -24664,6 +24665,7 @@ static const struct builtin_description bdesc_special_args[] = { { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtsc, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID }, { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtscp, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED }, + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID }, /* MMX */ { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_emms, "__builtin_ia32_emms", IX86_BUILTIN_EMMS, UNKNOWN, (int) VOID_FTYPE_VOID }, diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 49f1ee7..801573c 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -108,6 +108,7 @@ UNSPEC_TRUNC_NOOP UNSPEC_DIV_ALREADY_SPLIT UNSPEC_CALL_NEEDS_VZEROUPPER + UNSPEC_PAUSE ;; For SSE/MMX support: UNSPEC_FIX_NOTRUNC @@ -17716,6 +17717,25 @@ [(set_attr "type" "other") (set_attr "prefix_extra" "1")]) +(define_expand "pause" + [(set (match_dup 0) + (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] + "" +{ + operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[0]) = 1; +}) + +;; Use "rep; nop", instead of "pause", to support older assemblers. +;; They have the same encoding. +(define_insn "*pause" + [(set (match_operand:BLK 0 "" "") + (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] + "" + "rep; nop" + [(set_attr "length" "2") + (set_attr "memory" "unknown")]) + (include "mmx.md") (include "sse.md") (include "sync.md") diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h index 76c20a6..42ebd17 100644 --- a/gcc/config/i386/ia32intrin.h +++ b/gcc/config/i386/ia32intrin.h @@ -153,6 +153,14 @@ __rord (unsigned int __X, int __C) return (__X >> __C) | (__X << (32 - __C)); } +/* Pause */ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__pause (void) +{ + __builtin_ia32_pause (); +} + #ifdef __x86_64__ /* 64bit bsf */ extern __inline int diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index b5702db..bd2f080 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -8695,6 +8695,13 @@ __float128 __builtin_fabsq (__float128) __float128 __builtin_copysignq (__float128, __float128) @end smallexample +The following built-in function is always available. + +@table @code +@item void __builtin_ia32_pause (void) +Generates the @code{pause} machine instruction with full memory barrier. +@end table + The following floating point built-in functions are made available in the 64-bit mode. diff --git a/gcc/testsuite/gcc.target/i386/pause-1.c b/gcc/testsuite/gcc.target/i386/pause-1.c new file mode 100644 index 0000000..50eb8e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pause-1.c @@ -0,0 +1,11 @@ +/* Test that we generate pause instruction. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -dp" } */ +/* { dg-final { scan-assembler-times "\\*pause" 1 } } */ + +#include <x86intrin.h> + +void foo(void) +{ + __pause(); +}