arm.md (UNSPEC_LL): New.
* config/arm/arm.md (UNSPEC_LL): New. * config/arm/sync.md (atomic_loaddi, atomic_loaddi_1): New. (arm_load_exclusivedi): Use %H0. From-SVN: r186990
This commit is contained in:
parent
85dd555948
commit
a7b8107f8e
@ -1,3 +1,9 @@
|
||||
2012-04-30 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/arm/arm.md (UNSPEC_LL): New.
|
||||
* config/arm/sync.md (atomic_loaddi, atomic_loaddi_1): New.
|
||||
(arm_load_exclusivedi): Use %H0.
|
||||
|
||||
2012-04-30 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* dwarf2out.c (comdat_symbol_id): Add const.
|
||||
|
@ -117,6 +117,7 @@
|
||||
; that.
|
||||
UNSPEC_UNALIGNED_STORE ; Same for str/strh.
|
||||
UNSPEC_PIC_UNIFIED ; Create a common pic addressing form.
|
||||
UNSPEC_LL ; Represent an unpaired load-register-exclusive.
|
||||
])
|
||||
|
||||
;; UNSPEC_VOLATILE Usage:
|
||||
|
@ -65,6 +65,31 @@
|
||||
(set_attr "conds" "unconditional")
|
||||
(set_attr "predicable" "no")])
|
||||
|
||||
;; Note that ldrd and vldr are *not* guaranteed to be single-copy atomic,
|
||||
;; even for a 64-bit aligned address. Instead we use a ldrexd unparied
|
||||
;; with a store.
|
||||
(define_expand "atomic_loaddi"
|
||||
[(match_operand:DI 0 "s_register_operand") ;; val out
|
||||
(match_operand:DI 1 "mem_noofs_operand") ;; memory
|
||||
(match_operand:SI 2 "const_int_operand")] ;; model
|
||||
"TARGET_HAVE_LDREXD && ARM_DOUBLEWORD_ALIGN"
|
||||
{
|
||||
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
|
||||
expand_mem_thread_fence (model);
|
||||
emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
|
||||
if (model == MEMMODEL_SEQ_CST)
|
||||
expand_mem_thread_fence (model);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "atomic_loaddi_1"
|
||||
[(set (match_operand:DI 0 "s_register_operand" "=r")
|
||||
(unspec:DI [(match_operand:DI 1 "mem_noofs_operand" "Ua")]
|
||||
UNSPEC_LL))]
|
||||
"TARGET_HAVE_LDREXD && ARM_DOUBLEWORD_ALIGN"
|
||||
"ldrexd%?\t%0, %H0, %C1"
|
||||
[(set_attr "predicable" "yes")])
|
||||
|
||||
(define_expand "atomic_compare_and_swap<mode>"
|
||||
[(match_operand:SI 0 "s_register_operand" "") ;; bool out
|
||||
(match_operand:QHSD 1 "s_register_operand" "") ;; val out
|
||||
@ -317,16 +342,7 @@
|
||||
[(match_operand:DI 1 "mem_noofs_operand" "Ua")]
|
||||
VUNSPEC_LL))]
|
||||
"TARGET_HAVE_LDREXD"
|
||||
{
|
||||
rtx target = operands[0];
|
||||
/* The restrictions on target registers in ARM mode are that the two
|
||||
registers are consecutive and the first one is even; Thumb is
|
||||
actually more flexible, but DI should give us this anyway.
|
||||
Note that the 1st register always gets the lowest word in memory. */
|
||||
gcc_assert ((REGNO (target) & 1) == 0);
|
||||
operands[2] = gen_rtx_REG (SImode, REGNO (target) + 1);
|
||||
return "ldrexd%?\t%0, %2, %C1";
|
||||
}
|
||||
"ldrexd%?\t%0, %H0, %C1"
|
||||
[(set_attr "predicable" "yes")])
|
||||
|
||||
(define_insn "arm_store_exclusive<mode>"
|
||||
|
Loading…
Reference in New Issue
Block a user