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. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils