diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 009097e7513..c0242a9e62b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,9 +1,14 @@ 2012-03-02 Oleg Endo - * config/sh/sync.md: Update copyright notice dates. + * config/sh/sync.md (atomic_exchange): New expander. + (atomic_exchange_soft): New insn. + +2012-03-02 Oleg Endo + + * config/sh/sync.md: Update copyright notice dates. (atomic_compare_and_swap): Use SImode for return value instead of QImode. - (atomic_compare_and_swap_soft): Likewise. + (atomic_compare_and_swap_soft): Likewise. 2012-03-02 Oleg Endo diff --git a/gcc/config/sh/sync.md b/gcc/config/sh/sync.md index 88e0ce22089..5e55947b66b 100644 --- a/gcc/config/sh/sync.md +++ b/gcc/config/sh/sync.md @@ -164,6 +164,45 @@ } [(set_attr "length" "20")]) +(define_expand "atomic_exchange" + [(match_operand:I124 0 "register_operand" "") ;; oldval output + (match_operand:I124 1 "memory_operand" "") ;; memory + (match_operand:I124 2 "register_operand" "") ;; newval input + (match_operand:SI 3 "const_int_operand" "")] ;; memory model + "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA" +{ + rtx addr = force_reg (Pmode, XEXP (operands[1], 0)); + emit_insn (gen_atomic_exchange_soft + (operands[0], addr, operands[2])); + if (mode == QImode) + emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]), + operands[0])); + else if (mode == HImode) + emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[0]), + operands[0])); + DONE; +}) + +(define_insn "atomic_exchange_soft" + [(set (match_operand:I124 0 "register_operand" "=&u") + (mem:I124 (match_operand:SI 1 "register_operand" "u"))) + (set (mem:I124 (match_dup 1)) + (unspec:I124 + [(match_operand:I124 2 "register_operand" "u")] UNSPEC_ATOMIC)) + (clobber (reg:SI R0_REG)) + (clobber (reg:SI R1_REG))] + "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA" +{ + return "mova 1f,r0" "\n" + " .align 2" "\n" + " mov r15,r1" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " mov. %2,@%1" "\n" + "1: mov r1,r15"; +} + [(set_attr "length" "14")]) + (define_expand "atomic_fetch_" [(set (match_operand:I124 0 "register_operand" "") (match_operand:I124 1 "memory_operand" ""))