Q: Is this improper asm use or a bug?

Fred Fish fnf@intrinsity.com
Wed Jun 11 20:36:00 GMT 2003


Given the following source:

    static __inline__ void __delay(unsigned long loops)
    {
      __asm__ __volatile__ (
                    ".set\tnoreorder\n"
                    "1:\tbnez\t%1,1b\n\t"
                    "subu\t%0,1\n\t"
                    ".set\treorder"
                    : "+r" (loops)
                    : "0" (loops));
    }
    
    void func ()
    {
      __delay(50000);
    }

a current CVS version of mips-unknown-elf-gcc with -O produces:

            .file   1 "b.i"
            .section .mdebug.eabi32
            .previous
            .text
            .align  2
            .globl  func
            .ent    func
      func:
            .frame  $sp,0,$31               # vars= 0, regs= 0/0, args= 0, extra= 0
            .mask   0x00000000,0
            .fmask  0x00000000,0
     #APP
            .set    noreorder
      1:     bnez    $2,1b
             subu    $2,1
            .set    reorder
     #NO_APP
            j       $31
            .end    func
    
which disassembles as:

      00000000 <func>:
       0:   1440ffff        bnez    v0,0 <func>
       4:   2442ffff        addiu   v0,v0,-1
       8:   03e00008        jr      ra
       c:   00000000        nop

Note that the value "50000" has disappeared completely and the
loop starts with an initial value of whatever was in v0.

The *.01.sibling debug file has the following RTL:

    (note 22 9 10 0 [bb 0] NOTE_INSN_BASIC_BLOCK)
    
    (insn 10 22 11 0 (nil) (set (reg/v:SI 205 [ loops ])
            (const_int 50000 [0xc350])) -1 (nil)
        (nil))
    
    (note 11 10 14 0 0x4029aa00 NOTE_INSN_BLOCK_BEG)
    
    (insn 14 11 15 0 (nil) (set (reg/v:SI 205 [ loops ])
            (asm_operands/v:SI (".set       noreorder
    1:      bnez    %1,1b
            subu    %0,1
            .set    reorder") ("=r") 0 [
                    (reg/v:SI 205 [ loops ])
                    (reg/v:SI 205 [ loops ])
                ]
                 [
                    (asm_input:SI ("0"))
                    (asm_input:SI ("0"))
                ] ("b.i") 3)) -1 (nil)
        (nil))
    
    (note 15 14 17 0x4029aa00 NOTE_INSN_BLOCK_END)

And the *.03.jump output RTL is:

    (note 22 3 14 0 [bb 0] NOTE_INSN_BASIC_BLOCK)
    
    (insn 14 22 19 0 0x4029aa00 (set (reg/v:SI 205 [ loops ])
            (asm_operands/v:SI (".set       noreorder
    1:      bnez    %1,1b
            subu    %0,1
            .set    reorder") ("=r") 0 [
                    (reg/v:SI 205 [ loops ])
                    (reg/v:SI 205 [ loops ])
                ]
                 [
                    (asm_input:SI ("0"))
                    (asm_input:SI ("0"))
                ] ("b.i") 3)) -1 (nil)
        (nil))
    
Thanks for any clarification on whether this is a bug or simple misuse
of asm.

-Fred



More information about the Gcc mailing list