[Top][All Lists]
[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.
- [Bug gas/4124] New: ustq wrong code generation,
anton at mips dot complang dot tuwien dot ac dot at <=