Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Question for the Crafty/Compiler experts (more)

Author: Dieter Buerssner

Date: 04:20:11 02/20/04

Go up one level in this thread


On February 19, 2004 at 22:39:47, Robert Hyatt wrote:

>On February 19, 2004 at 16:44:38, Dieter Buerssner wrote:
>
>>On February 19, 2004 at 16:16:23, Robert Hyatt wrote:
>>
>>>I looked at my old inline asm docs, and I found the following statement,
>>>paraphrased:
>>>
>>>"you don't need to put gcc-allocated registers on the clobber list, it knows you
>>>are fooling with them."
>>
>>That's news to me. I cannot find it in my gcc manual (and I know, that it did
>>not work with earlier gcc versions).
>>
>>Some snippets of my gcc manual:
>>
>>---
>>The compiler cannot check whether the operands have data types that are
>>reasonable for the instruction being executed.  It does not parse the assembler
>>instruction template and does not know what it means or even whether it is valid
>>assembler input.
>>
>>[...]
>>   Some instructions clobber specific hard registers.  To describe this,
>                                       ^^^^^^^^^^^^^^^
>
>I am keying on that in your quote.  "hard register" as opposed to "dynamically
>assigned register"...  I won't say that is a correct interpretation, of course.
>The syntax is not horrible for inline asm, but the documentation leaves a lot to
>be desired, clarity-wise...

To me, it looks rather clear, that you must notify the compiler, if you modify
an input operand. Later in the Gcc manula, it is also explicetly mentioned, that
they are assumed as read only operands. It is also mentioned, that it does not
try at all, to understand the inline assembler, it just puts in the real
operands instead of the %0/1/2...

A little test case. Your popcount slightly modified, so that the input will be
used later (it might happen similarily in real code when inlining).


int bob(unsigned long a, unsigned long b)
{
/*  r0=result, %1=tmp, %2=first input, %3=second input */
  long      dummy, dummy2;

asm("        xorl    %0, %0"                    "\n\t"
    "        testl   %2, %2"                    "\n\t"
    "        jz      2f"                        "\n\t"
    "1:      leal    -1(%2), %1"                "\n\t"
    "        incl    %0"                        "\n\t"
    "        andl    %1, %2"                    "\n\t"
    "        jnz     1b"                        "\n\t"
    "2:      testl   %3, %3"                    "\n\t"
    "        jz      4f"                        "\n\t"
    "3:      leal    -1(%3), %1"                "\n\t"
    "        incl    %0"                        "\n\t"
    "        andl    %1, %3"                    "\n\t"
    "        jnz     3b"                        "\n\t"
    "4:"                                        "\n\t"
  : "=&q" (dummy), "=&q" (dummy2)
  : "q" (a), "q" (b)
  : "cc");
  return dummy+a+b;
}

/* Too lazy, to format nicely, also really untested */
int dieter(unsigned long a, unsigned long b)
{
  int tmp, tmp2, n;
  __asm__ __volatile__(
   "movl %3, %1  \n\t"
   "xorl %0, %0  \n\t"
   "testl %1, %1  \n\t"
   "je 1f  \n\t"
   "0: incl %0  \n\t"
   "leal -1(%1), %2  \n\t"
   "andl %2, %1  \n\t"
   "jne 0b  \n\t"
   "1: movl %4, %1  \n\t"
   "testl %1, %1  \n\t"
   "je 3f  \n\t"
   "2: incl %0  \n\t"
   "leal -1(%1), %2  \n\t"
   "andl %2, %1  \n\t"
   "jne 2b  \n\t"
   "3:"
   : "=r&" (n), "=r&" (tmp), "=r&" (tmp2)
   : "g" (a), "g" (b)
   : "cc" /* Flags "condition code" changed */);
  return n+a+b;
}

gcc -O -S produces (I added some ; comments):

	.file	"bob.c"
	.section .text
	.p2align 1
.globl _bob
_bob:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	movl	8(%ebp), %edx
; a to edx
	movl	12(%ebp), %ecx
; b to ecx
/APP
	        xorl    %eax, %eax
	        testl   %edx, %edx
	        jz      2f
	1:      leal    -1(%edx), %ebx
	        incl    %eax
	        andl    %ebx, %edx
; edx modified
	        jnz     1b
	2:      testl   %ecx, %ecx
	        jz      4f
	3:      leal    -1(%ecx), %ebx
	        incl    %eax
	        andl    %ebx, %ecx
; ecx modified
	        jnz     3b
	4:

/NO_APP
	addl	%edx, %eax
; oops using edx again, thinking it is not modified
	addl	%ecx, %eax
; ditto ecx
	popl	%ebx
	popl	%ebp
	ret
	.p2align 1
.globl _dieter
_dieter:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%esi
	pushl	%ebx
	movl	8(%ebp), %edx
	movl	12(%ebp), %ecx
/APP
	movl %edx, %esi
	xorl %eax, %eax
	testl %esi, %esi
	je 1f
	0: incl %eax
	leal -1(%esi), %ebx
	andl %ebx, %esi
	jne 0b
	1: movl %ecx, %esi
	testl %esi, %esi
	je 3f
	2: incl %eax
	leal -1(%esi), %ebx
	andl %ebx, %esi
	jne 2b
	3:
/NO_APP
; using unmodified a and b here
	addl	%edx, %eax
	addl	%ecx, %eax
	popl	%ebx
	popl	%esi
	popl	%ebp
	ret
	.ident	"GCC: (GNU) 3.2"

Regards,
Dieter




This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.