From: haible@ma2s2.mathematik.uni-karlsruhe.de (Bruno Haible)
Subject: asm clobbers condition code
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 8 Apr 1992 01:11:32 GMT

I have some __asm__ statements in my code. They modify the condition code (CCR)
register (zero-flag etc.). But GCC (scheduler) moves some CCR modifying
instructions before the __asm__, leaving the CCR testing instruction after it.

- Must I declare that my __asm__ clobbers CCR? If yes, how?

- Must I instead declare my __asm__ volatile? (This would apply to MOST
  asm code!)

- Should this be a GCC bug? If yes, here's the piece of source (gcc21bug.i)
  and output from 'gcc -O2 -S gcc21bug.c ; cat gcc21bug.s.' :
  (The full file is rather big; I avoid sending it per email, but you can get
   it via "ftp 129.13.115.2 , cd /pub/gnu , mget gcc21bug.*" .)

================================================================================
              {   register  uintL count;
               { count = (m);  while(!(count==0))  {
                 {    register  uintB* label_byteptr;
                   {    register  uintL where; {    register  uintL dummy; __asm__("                  ldub [%1],%0       ;                   andcc %0,0x80,%%g0 ;                   be 2f              ;                    add %1,1,%1       ;                   sll %0,25,%2       ;                   ldub [%1],%0       ;                   sra %2,17,%2       ;                   orcc %2,%0,%0      ;                   bne 3f             ;                    add %1,1,%1       ;                   ldub [%1],%0       

;                   sll %0,24,%2       ;                   ldub [%1+1],%0     ;                   sll %0,16,%0       ;                   or %2,%0,%2        ;                   ldub [%1+2],%0     ;                   sll %0,8,%0        ;                   or %2,%0,%2        ;                   ldub [%1+3],%0     ;                   or %2,%0,%0        ;                   b 3f               ;                    add %1,4,%1       ;                   2:                           !
          sll %0,25,%0       ;   
                    ( (STACK[-1-(-1)])  = (((object)( ((oint)(tint)(   0x10  ) << 24 ) + (oint)(aint)(label_byteptr -  (uintB*)(codeptr) ) )) ), STACK  -=  -1) ;
                 }; count--; } } ;
              }
================================================================================
	cmp %l1,0
	be L249
	mov %l1,%o2
	sethi %hi(268435456),%o3
L250:
	ld [%fp-36],%g3
	ld [%fp-28],%g2
	addcc %o2,-1,%o2
	                  ldub [%g3],%o0       ;                   andcc %o0,0x80,%g0 ;                   be 2f              ;                    add %g3,1,%g3       ;                   sll %o0,25,%o1       ;                   ldub [%g3],%o0       ;                   sra %o1,17,%o1       ;                   orcc %o1,%o0,%o0      ;                   bne 3f             ;                    add %g3,1,%g3       ;                   ldub [%g3],%o0       ;                   sll %o0,24,%o1       ;                   ldub 

[%g3+1],%o0     ;                   sll %o0,16,%o0       ;                   or %o1,%o0,%o1        ;                   ldub [%g3+2],%o0     ;                   sll %o0,8,%o0        ;                   or %o1,%o0,%o1        ;                   ldub [%g3+3],%o0     ;                   or %o1,%o0,%o0        ;                   b 3f               ;                    add %g3,4,%g3       ;                   2:                                     sll %o0,25,%o0       ;           !
        sra %o0,25,%o0       ;   
	st %g3,[%fp-36]
	add %g3,%o0,%o0
	sub %o0,%g2,%o0
	add %o0,%o3,%o0
	st %o0,[%g5]
	bne L250
	add %g5,4,%g5
L249:
================================================================================
I'm using GCC version 2.1,
configured as sparc-sun4-sunos4, that is, having the links
 aux-output.c -> ./config/sparc.c
 config.h -> ./config/xm-sparc.h
 md -> ./config/sparc.md
 tconfig.h -> ./config/xm-sparc.h
 tm.h -> ./config/sparc.h

B. Haible

Newsgroups: gnu.gcc.bug