From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6745 invoked by alias); 30 May 2014 11:38:44 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 6717 invoked by uid 48); 30 May 2014 11:38:40 -0000 From: "gcc.hall at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug inline-asm/49611] Inline asm should support input/output of flags Date: Fri, 30 May 2014 11:38:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: inline-asm X-Bugzilla-Version: 4.5.2 X-Bugzilla-Keywords: X-Bugzilla-Severity: enhancement X-Bugzilla-Who: gcc.hall at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-05/txt/msg02546.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611 Jeremy changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |gcc.hall at gmail dot com --- Comment #5 from Jeremy --- It may not be possible, but perhaps a simpler thing might be for the asm() to notionally "return" a single boolean value which reflects ONE flag only. By default this could be the ZF flag (which is probably the most useful). It would not generate any extra code at all. Thus: if( asm( "test %%eax,%%eax" )) would emit: test eax,eax jz rather than the usual route involving setcc and a second test. The actual flag notionally returned could be changed with an attribute: __attribute__ ((asm_return(cc_carry))) __attribute__ ((asm_return(cc_overflow))) __attribute__ ((asm_return(cc_zero))) __attribute__ ((asm_return(cc_sign))) __attribute__ ((asm_return(cc_parity))) or shorter, for example: __attribute__ ((cc_carry)) The inverse condition is simply expressed with !asm(...) The new code would also allow: bool zero = asm( "test %%eax,%%eax" ); where the compiler would emit setz. or x = asm( "test %%eax,%%eax" ) ? 10 : 20; where the compiler might emit cmovz. It would not break any existing code because nothing yet expects a return from an asm, neither would it preclude exporting all the flags with "=cc" in the future. It would be a hard error if a flag is not supported by the current platform as code cannnot be generated. GCC does not examine the asm template string, if the flag is not set then the result is UB, just like use of an undefined variable. A final, more useful, example: // Implement "left *= right" reporting signed integer overflow #define checked_multiply(left,right) \ __attribute__ ((asm_return(cc_overflow))) \ asm( "imul %1,%0" : "+r" (left) : "r" (right) ) allowing an efficient implementation of: if( checked_multiply( a, b ) ) { handle overflow } Possible documentation follows... ======================== Return Value If you are using the asm_return attribute, you are informing the compiler that a comparison has already been done in your assembler code, and the flags have been set appropriately. The compiler can now use those flags to perform conditional jumps, conditional assignments, etc. Which conditional operator should be used is determined by which value is specified to asm_return. For example on i386: if( __attribute__(asm_return(cc_carry)) asm() ) printf ("Carry yes\n"); else printf ("Carry no\n"); indicates that the asm template has set a value in the Carry flag, and GCC should use the jc/jnc instructions to jump to the correct location. Similarly: int a = __attribute__(asm_return(cc_zero)) asm() ? 23 : 42; could use the i386 cmovz instruction to perform the assignment. And bool DidOverflow = __attribute__(asm_return(cc_overflow)) asm(); could use i386's seto. Which flags (if any) are supported depend upon your platform (see Asm Attributes). If no asm_return attribute is specified, it is an error to attempt to use the return value from the asm. It is acceptable for code to ignore the returned flags. ========================