bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gas/4124] New: ustq wrong code generation


From: anton at mips dot complang dot tuwien dot ac dot at
Subject: [Bug gas/4124] New: ustq wrong code generation
Date: 2 Mar 2007 15:26:27 -0000

gas generates the following code for ustq:

  1c:   00 00 90 23     lda     at,0(a0)
  20:   00 00 fc 2e     ldq_u   t9,0(at)
  24:   07 00 1c 2f     ldq_u   t10,7(at)
  28:   79 07 3c 48     insql   t0,at,t11
  2c:   fb 0e 3c 48     insqh   t0,at,t12
  30:   57 06 fc 4a     mskql   t9,at,t9
  34:   58 0e 1c 4b     mskqh   t10,at,t10
  38:   17 04 f9 46     or      t9,t11,t9
  3c:   18 04 1b 47     or      t10,t12,t10
  40:   00 00 fc 3e     stq_u   t9,0(at)
  44:   07 00 1c 3f     stq_u   t10,7(at)

The last two instructions are in the wrong order: if the address is
aligned, the two stores will store to the same effective address, but
the correct value to store is in t9 (whereas t10 contains the old
value).

Test program:

#include <stdio.h>

main()
{
  long b=1;
  asm("ustq $31,0(%0)"::"r"(&b));
  printf("b=%d (expected: 0)\n",b);
  return 0;
}

(assemble it with the Digital Unix assembler or use stq instead of
ustq to see the correct behaviour).

Just for comparison, the Digital Unix assembler generates the
following for ustq:

  [x1.s:  20] 0x1c:     23900000        lda     at, 0(a0)
  [x1.s:  20] 0x20:     2efc0000        ldq_u   t9, 0(at)
  [x1.s:  20] 0x24:     2f1c0007        ldq_u   t10, 7(at)
  [x1.s:  20] 0x28:     483c0ef9        insqh   t0, at, t11
  [x1.s:  20] 0x2c:     483c077b        insql   t0, at, t12
  [x1.s:  20] 0x30:     4b1c0e58        mskqh   t10, at, t10
  [x1.s:  20] 0x34:     4afc0657        mskql   t9, at, t9
  [x1.s:  20] 0x38:     47190418        bis     t10, t11, t10
  [x1.s:  20] 0x3c:     46fb0417        bis     t9, t12, t9
  [x1.s:  20] 0x40:     3f1c0007        stq_u   t10, 7(at)
  [x1.s:  20] 0x44:     3efc0000        stq_u   t9, 0(at)

ustw and ustl have the same bug (with a higher probability to result
in wrong results).  Test program:

#include <stdio.h>

main()
{
  long b=1;
  int c[]={1,1};
  short d[]={1,2,3,4};
  int i;
  asm("ustq $31,0(%0)"::"r"(&b));
  printf("b=%d (expected: 0)\n",b);
  for (i=0; i<2; i++) {
    asm("ustl $31,0(%0)"::"r"(c+i));
    printf("c[i]=%d (expected: 0)\n",c[i]);
  }
  for (i=0; i<4; i++) {
    asm("ustw $31,0(%0)"::"r"(d+i));
    printf("d[i]=%d (expected: 0)\n",d[i]);
  }
  return 0;
}

And here's a patch for fixing these bugs:

--- binutils-2.17/gas/config/tc-alpha.c~        2005-11-16 02:49:48.000000000 
+0100
+++ binutils-2.17/gas/config/tc-alpha.c 2007-03-02 15:35:33.000000000 +0100
@@ -2383,15 +2383,15 @@
   newtok[2] = newtok[0];
   assemble_tokens ("or", newtok, 3, 1);
 
-  /* Emit "stq_u $t9, 0($at)".  */
-  set_tok_reg (newtok[0], AXP_REG_T9);
-  set_tok_const (newtok[1], 0);
-  set_tok_preg (newtok[2], AXP_REG_AT);
-  assemble_tokens ("stq_u", newtok, 3, 1);
-
   /* Emit "stq_u $t10, size-1($at)".  */
   set_tok_reg (newtok[0], AXP_REG_T10);
   set_tok_const (newtok[1], (1 << lgsize) - 1);
+  set_tok_preg (newtok[2], AXP_REG_AT);
+  assemble_tokens ("stq_u", newtok, 3, 1);
+
+  /* Emit "stq_u $t9, 0($at)".  */
+  set_tok_reg (newtok[0], AXP_REG_T9);
+  set_tok_const (newtok[1], 0);
   assemble_tokens ("stq_u", newtok, 3, 1);
 }

-- 
           Summary: ustq wrong code generation
           Product: binutils
           Version: 2.17
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gas
        AssignedTo: unassigned at sources dot redhat dot com
        ReportedBy: anton at mips dot complang dot tuwien dot ac dot at
                CC: bug-binutils at gnu dot org
 GCC build triplet: alpha-unknown-linux-gnu
  GCC host triplet: alpha-unknown-linux-gnu
GCC target triplet: alpha-unknown-linux-gnu


http://sourceware.org/bugzilla/show_bug.cgi?id=4124

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]