From patchwork Wed Dec 4 16:59:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kirill Yukhin X-Patchwork-Id: 296587 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 098172C0097 for ; Thu, 5 Dec 2013 04:02:33 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=WpU8pcYSqYCkfecbmYBjg19wzu4Pi09zAcnlU++iGXtUxP2Nhi YkxVaxCbl6bFjk+nI1rg+9mDwOnhzdV/fongXV9hIL+oXjCYtbm0cQX8ukMiQdmD B0kJwqrK6KClQoa5QcEuakeEzjowDQkmqVUk8FBntXEHW17lcoUbam3Zw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=QlxH5cHd7oPwoUFcT2i959ULiK8=; b=qN7kTJ7UtOymQQbFuswx ui4Yfw6+LNdmdbRvqCIpaKDgiysGJcIMzk73Kdox2txIK2+TdcBYLUnDpiyLbgPP 21YrHn86go8/mhF8dyXHtMdV7X05dJYi2QKRZBDammTjoqQ7jz0sxltCegghYrGp SIwE/kgkQymretXGwvpxEbA= Received: (qmail 14023 invoked by alias); 4 Dec 2013 17:02:23 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 14008 invoked by uid 89); 4 Dec 2013 17:02:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.3 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, RDNS_NONE, SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-pb0-f49.google.com Received: from Unknown (HELO mail-pb0-f49.google.com) (209.85.160.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 04 Dec 2013 17:02:06 +0000 Received: by mail-pb0-f49.google.com with SMTP id jt11so23559188pbb.8 for ; Wed, 04 Dec 2013 09:01:58 -0800 (PST) X-Received: by 10.68.164.165 with SMTP id yr5mr19163635pbb.146.1386176518178; Wed, 04 Dec 2013 09:01:58 -0800 (PST) Received: from msticlxl57.ims.intel.com (fmdmzpr01-ext.fm.intel.com. [192.55.54.36]) by mx.google.com with ESMTPSA id qz9sm137320858pbc.3.2013.12.04.09.01.55 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 04 Dec 2013 09:01:57 -0800 (PST) Date: Wed, 4 Dec 2013 19:59:48 +0300 From: Kirill Yukhin To: Uros Bizjak Cc: Jakub Jelinek , GCC Patches Subject: [PATCH i386] Introduce __readeflags () and __writeeflags () intrinsics. Message-ID: <20131204165948.GA21551@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Hello, MSVC and ICC (currently Windows version, Linux version soon) have dedicated intrinsics to read/set EFLAGS register ([1], [2]). Patch introduces these intrinsics and tests for them. Bootstrapped. New tests pass. Although gate is closed patch is obvious. So, is it ok for trunk? ChangeLog/ * config/i386/ia32intrin.h (__readeflags): New. (__writeeflags): Ditto. testsuite/ChangeLog/ * gcc.target/i386/readeflags-1.c: New. * gcc.target/i386/writeeflags-1.c: Ditto. [1] - http://msdn.microsoft.com/en-us/library/aa983406(v=vs.90).aspx [2] - http://msdn.microsoft.com/en-us/library/aa983392(v=vs.90).aspx --- Thanks, K diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h index b26dc46..c9e68c5 100644 --- a/gcc/config/i386/ia32intrin.h +++ b/gcc/config/i386/ia32intrin.h @@ -238,6 +238,34 @@ __rorq (unsigned long long __X, int __C) return (__X >> __C) | (__X << (64 - __C)); } +/* Read flags register */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__readeflags (void) +{ + unsigned long long result = 0; + __asm__ __volatile__ ("pushf\n\t" + "popq %0\n" + :"=r"(result) + : + : + ); + return result; +} + +/* Write flags register */ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__writeeflags (unsigned long long X) +{ + __asm__ __volatile__ ("pushq %0\n\t" + "popf\n" + : + :"r"(X) + :"flags" + ); +} + #define _bswap64(a) __bswapq(a) #define _popcnt64(a) __popcntq(a) #define _lrotl(a,b) __rolq((a), (b)) @@ -245,6 +273,35 @@ __rorq (unsigned long long __X, int __C) #else #define _lrotl(a,b) __rold((a), (b)) #define _lrotr(a,b) __rord((a), (b)) + +/* Read flags register */ +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__readeflags (void) +{ + unsigned int result = 0; + __asm__ __volatile__ ("pushf\n\t" + "popl %0\n" + :"=r"(result) + : + : + ); + return result; +} + +/* Write flags register */ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__writeeflags (unsigned int X) +{ + __asm__ __volatile__ ("pushl %0\n\t" + "popf\n" + : + :"r"(X) + :"flags" + ); +} + #endif #define _bit_scan_forward(a) __bsfd(a) diff --git a/gcc/testsuite/gcc.target/i386/readeflags-1.c b/gcc/testsuite/gcc.target/i386/readeflags-1.c new file mode 100644 index 0000000..6b2fa7e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/readeflags-1.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O0" } */ + +#include + +#ifdef __x86_64__ +#define EFLAGS_TYPE unsigned long long int +#else +#define EFLAGS_TYPE unsigned int +#endif + +static EFLAGS_TYPE +readeflags_test (unsigned int a, unsigned int b) +{ + unsigned x = (a == b); + return __readeflags (); +} + +int +main () +{ + EFLAGS_TYPE flags; + + flags = readeflags_test (100, 100); + + if ((flags & 1) != 0) /* Read CF */ + abort (); + + flags = readeflags_test (100, 101); + + if ((flags & 1) == 0) /* Read CF */ + abort (); + +#ifdef DEBUG + printf ("PASSED\n"); +#endif + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/i386/writeeflags-1.c b/gcc/testsuite/gcc.target/i386/writeeflags-1.c new file mode 100644 index 0000000..446840c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/writeeflags-1.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-O0" } */ + +#include + +#ifdef __x86_64__ +#define EFLAGS_TYPE unsigned long long int +#else +#define EFLAGS_TYPE unsigned int +#endif + +int +main () +{ + EFLAGS_TYPE flags = 0xD7; /* 111010111b */ + + __writeeflags (flags); + + flags = __readeflags (); + + if ((flags & 0xFF) != 0xD7) + abort (); + +#ifdef DEBUG + printf ("PASSED\n"); +#endif + + return 0; +} +