aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/sync.md
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2007-03-19 17:07:29 +0000
committerMichael Matz <matz@gcc.gnu.org>2007-03-19 17:07:29 +0000
commit1e395249a9f9be3050998a40aabf38e4fa863a37 (patch)
treeddb2d551ea09bfec19c57fe8cc9e9c371f68943a /gcc/config/i386/sync.md
parentb5e5ca5fd3cba74accddb31d4b076686dbb271c1 (diff)
downloadgcc-1e395249a9f9be3050998a40aabf38e4fa863a37.zip
gcc-1e395249a9f9be3050998a40aabf38e4fa863a37.tar.gz
gcc-1e395249a9f9be3050998a40aabf38e4fa863a37.tar.bz2
builtins.c (expand_builtin_sync_operation, [...]): Care for extending CONST_INTs correctly.
* builtins.c (expand_builtin_sync_operation, expand_builtin_compare_and_swap, expand_builtin_lock_test_and_set): Care for extending CONST_INTs correctly. * config/i386/sync.md (sync_double_compare_and_swapdi_pic, sync_double_compare_and_swap_ccdi_pic): Use "SD" as constraint for operand 3. From-SVN: r123064
Diffstat (limited to 'gcc/config/i386/sync.md')
-rw-r--r--gcc/config/i386/sync.md15
1 files changed, 13 insertions, 2 deletions
diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index 58e047b..9a0ae3f 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -98,6 +98,15 @@
""
"lock{\;| }cmpxchg<doublemodesuffix>b{\t| }%1")
+;; Theoretically we'd like to use constraint "r" (any reg) for operand
+;; 3, but that includes ecx. If operand 3 and 4 are the same (like when
+;; the input is -1LL) GCC might chose to allocate operand 3 to ecx, like
+;; operand 4. This breaks, as the xchg will move the PIC register contents
+;; to %ecx then --> boom. Operands 3 and 4 really need to be different
+;; registers, which in this case means operand 3 must not be ecx.
+;; Instead of playing tricks with fake early clobbers or the like we
+;; just enumerate all regs possible here, which (as this is !TARGET_64BIT)
+;; are just esi and edi.
(define_insn "*sync_double_compare_and_swapdi_pic"
[(set (match_operand:DI 0 "register_operand" "=A")
(match_operand:DI 1 "memory_operand" "+m"))
@@ -105,7 +114,7 @@
(unspec_volatile:DI
[(match_dup 1)
(match_operand:DI 2 "register_operand" "A")
- (match_operand:SI 3 "register_operand" "r")
+ (match_operand:SI 3 "register_operand" "SD")
(match_operand:SI 4 "register_operand" "c")]
UNSPECV_CMPXCHG_1))
(clobber (reg:CC FLAGS_REG))]
@@ -189,6 +198,8 @@
""
"lock{\;| }cmpxchg<doublemodesuffix>b{\t| }%1")
+;; See above for the explanation of using the constraint "SD" for
+;; operand 3.
(define_insn "*sync_double_compare_and_swap_ccdi_pic"
[(set (match_operand:DI 0 "register_operand" "=A")
(match_operand:DI 1 "memory_operand" "+m"))
@@ -196,7 +207,7 @@
(unspec_volatile:DI
[(match_dup 1)
(match_operand:DI 2 "register_operand" "A")
- (match_operand:SI 3 "register_operand" "r")
+ (match_operand:SI 3 "register_operand" "SD")
(match_operand:SI 4 "register_operand" "c")]
UNSPECV_CMPXCHG_1))
(set (reg:CCZ FLAGS_REG)