From: Adrian Straetling Date: Wed, 7 Dec 2005 20:01:30 +0000 (+0000) Subject: s390.c (s390_expand_atomic): New function. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=45d18331f6fef4363e14fd19871ef765d1203472;p=platform%2Fupstream%2Fgcc.git s390.c (s390_expand_atomic): New function. 2005-12-07 Adrian Straetling * config/s390/s390.c (s390_expand_atomic): New function. Adjust comment of helper functions. * config/s390/s390-protos.h (s390_expand_atomic): Declare. * config/s390/s390.md ("ATOMIC"): New code macro. ("atomic"): Corresponding new code attribute. ("sync_lock_test_and_set[hq]i", "sync_{new_,old_,}{and,ior,xor,add,sub,nand}[hq]i"): New pattern. From-SVN: r108180 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b7b8ff8..37f83ad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2005-12-07 Adrian Straetling + * config/s390/s390.c (s390_expand_atomic): New function. + Adjust comment of helper functions. + * config/s390/s390-protos.h (s390_expand_atomic): Declare. + * config/s390/s390.md ("ATOMIC"): New code macro. + ("atomic"): Corresponding new code attribute. + ("sync_lock_test_and_set[hq]i", + "sync_{new_,old_,}{and,ior,xor,add,sub,nand}[hq]i"): New pattern. + +2005-12-07 Adrian Straetling + * config/s390/s390.c (s390_expand_mask_and_shift, struct alignment_context, init_alignment_context, s390_expand_cs_hqi): New. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index bb1516a..e62493d 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -76,6 +76,8 @@ extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx); extern bool s390_expand_addcc (enum rtx_code, rtx, rtx, rtx, rtx, rtx); extern bool s390_expand_insv (rtx, rtx, rtx, rtx); extern void s390_expand_cs_hqi (enum machine_mode, rtx, rtx, rtx, rtx); +extern void s390_expand_atomic (enum machine_mode, enum rtx_code, + rtx, rtx, rtx, bool); extern rtx s390_return_addr_rtx (int, rtx); extern rtx s390_back_chain_rtx (void); extern rtx s390_emit_call (rtx, rtx, rtx, rtx); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 880ebdd..901b9b5 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -3972,8 +3972,8 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) return false; } -/* A subroutine of s390_expand_cs_hqi which returns a register which holds VAL - of mode MODE shifted by COUNT bits. */ +/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a + register that holds VAL of mode MODE shifted by COUNT bits. */ static inline rtx s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count) @@ -3996,10 +3996,10 @@ struct alignment_context bool aligned; /* True if memory is aliged, false else. */ }; -/* A subroutine of s390_expand_cs_hqi to initialize the structure AC for - transparent simplifying, if the memory alignment is known to be at least - 32bit. MEM is the memory location for the actual operation and MODE its - mode. */ +/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize + structure AC for transparent simplifying, if the memory alignment is known + to be at least 32bit. MEM is the memory location for the actual operation + and MODE its mode. */ static void init_alignment_context (struct alignment_context *ac, rtx mem, @@ -4122,6 +4122,97 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx ne NULL_RTX, 1, OPTAB_DIRECT), 1); } +/* Expand an atomic operation CODE of mode MODE. MEM is the memory location + and VAL the value to play with. If AFTER is true then store the the value + MEM holds after the operation, if AFTER is false then store the value MEM + holds before the operation. If TARGET is zero then discard that value, else + store it to TARGET. */ + +void +s390_expand_atomic (enum machine_mode mode, enum rtx_code code, + rtx target, rtx mem, rtx val, bool after) +{ + struct alignment_context ac; + rtx cmp; + rtx new = gen_reg_rtx (SImode); + rtx orig = gen_reg_rtx (SImode); + rtx csloop = gen_label_rtx (); + + gcc_assert (!target || register_operand (target, VOIDmode)); + gcc_assert (MEM_P (mem)); + + init_alignment_context (&ac, mem, mode); + + /* Shift val to the correct bit positions. + Preserve "icm", but prevent "ex icm". */ + if (!(ac.aligned && code == SET && MEM_P (val))) + val = s390_expand_mask_and_shift (val, mode, ac.shift); + + /* Further preparation insns. */ + if (code == PLUS || code == MINUS) + emit_move_insn (orig, val); + else if (code == MULT || code == AND) /* val = "11..111..1" */ + val = expand_simple_binop (SImode, XOR, val, ac.modemaski, + NULL_RTX, 1, OPTAB_DIRECT); + + /* Load full word. Subsequent loads are performed by CS. */ + cmp = force_reg (SImode, ac.memsi); + + /* Start CS loop. */ + emit_label (csloop); + emit_move_insn (new, cmp); + + /* Patch new with val at correct position. */ + switch (code) + { + case PLUS: + case MINUS: + val = expand_simple_binop (SImode, code, new, orig, + NULL_RTX, 1, OPTAB_DIRECT); + val = expand_simple_binop (SImode, AND, val, ac.modemask, + NULL_RTX, 1, OPTAB_DIRECT); + /* FALLTHRU */ + case SET: + if (ac.aligned && MEM_P (val)) + store_bit_field (new, GET_MODE_BITSIZE (mode), 0, SImode, val); + else + { + new = expand_simple_binop (SImode, AND, new, ac.modemaski, + NULL_RTX, 1, OPTAB_DIRECT); + new = expand_simple_binop (SImode, IOR, new, val, + NULL_RTX, 1, OPTAB_DIRECT); + } + break; + case AND: + case IOR: + case XOR: + new = expand_simple_binop (SImode, code, new, val, + NULL_RTX, 1, OPTAB_DIRECT); + break; + case MULT: /* NAND */ + new = expand_simple_binop (SImode, XOR, new, ac.modemask, + NULL_RTX, 1, OPTAB_DIRECT); + new = expand_simple_binop (SImode, AND, new, val, + NULL_RTX, 1, OPTAB_DIRECT); + break; + default: + gcc_unreachable (); + } + /* Emit compare_and_swap pattern. */ + emit_insn (gen_sync_compare_and_swap_ccsi (cmp, ac.memsi, cmp, new)); + + /* Loop until swapped (unlikely?). */ + s390_emit_jump (csloop, gen_rtx_fmt_ee (NE, CCZ1mode, + gen_rtx_REG (CCZ1mode, CC_REGNUM), + const0_rtx)); + + /* Return the correct part of the bitfield. */ + if (target) + convert_move (target, expand_simple_binop (SImode, LSHIFTRT, + after ? new : cmp, ac.shift, + NULL_RTX, 1, OPTAB_DIRECT), 1); +} + /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL. We need to emit DTP-relative relocations. */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index d75015d..cf484c3 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -315,6 +315,11 @@ ;; the same template. (define_code_macro SHIFT [ashift lshiftrt]) +;; These macros allow to combine most atomic operations. +(define_code_macro ATOMIC [and ior xor plus minus mult]) +(define_code_attr atomic [(and "and") (ior "ior") (xor "xor") + (plus "add") (minus "sub") (mult "nand")]) + ;; In FPR templates, a string like "ltbr" will expand to "ltdbr" in DFmode ;; and "ltebr" in SFmode. @@ -7340,6 +7345,45 @@ (set_attr "type" "sem")]) +; +; Other atomic instruction patterns. +; + +(define_expand "sync_lock_test_and_set" + [(match_operand:HQI 0 "register_operand") + (match_operand:HQI 1 "memory_operand") + (match_operand:HQI 2 "general_operand")] + "" + "s390_expand_atomic (mode, SET, operands[0], operands[1], + operands[2], false); DONE;") + +(define_expand "sync_" + [(set (match_operand:HQI 0 "memory_operand") + (ATOMIC:HQI (match_dup 0) + (match_operand:HQI 1 "general_operand")))] + "" + "s390_expand_atomic (mode, , NULL_RTX, operands[0], + operands[1], false); DONE;") + +(define_expand "sync_old_" + [(set (match_operand:HQI 0 "register_operand") + (match_operand:HQI 1 "memory_operand")) + (set (match_dup 1) + (ATOMIC:HQI (match_dup 1) + (match_operand:HQI 2 "general_operand")))] + "" + "s390_expand_atomic (mode, , operands[0], operands[1], + operands[2], false); DONE;") + +(define_expand "sync_new_" + [(set (match_operand:HQI 0 "register_operand") + (ATOMIC:HQI (match_operand:HQI 1 "memory_operand") + (match_operand:HQI 2 "general_operand"))) + (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))] + "" + "s390_expand_atomic (mode, , operands[0], operands[1], + operands[2], true); DONE;") + ;; ;;- Miscellaneous instructions. ;;