diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/s390/htmxlintrin.h | 25 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 44 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 32 |
3 files changed, 60 insertions, 41 deletions
diff --git a/gcc/config/s390/htmxlintrin.h b/gcc/config/s390/htmxlintrin.h index 800d5f0..d1c7ec5 100644 --- a/gcc/config/s390/htmxlintrin.h +++ b/gcc/config/s390/htmxlintrin.h @@ -33,13 +33,20 @@ extern "C" { the IBM XL compiler. For documentation please see the "z/OS XL C/C++ Programming Guide" publicly available on the web. */ -extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +/* FIXME: __TM_simple_begin and __TM_begin should be marked + __always_inline__ as well but this currently produces an error + since the tbegin builtins are "returns_twice" and setjmp_call_p + (calls.c) therefore identifies the functions as calling setjmp. + The tree inliner currently refuses to inline functions calling + setjmp. */ + +long __TM_simple_begin () { return __builtin_tbegin_nofloat (0); } -extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +long __TM_begin (void* const tdb) { return __builtin_tbegin_nofloat (tdb); @@ -78,7 +85,7 @@ __TM_nesting_depth (void* const tdb_ptr) if (depth != 0) return depth; - if (tdb->format == 0) + if (tdb->format != 1) return 0; return tdb->nesting_depth; } @@ -90,7 +97,7 @@ __TM_is_user_abort (void* const tdb_ptr) { struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; - if (tdb->format == 0) + if (tdb->format != 1) return 0; return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE); @@ -101,7 +108,7 @@ __TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code) { struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; - if (tdb->format == 0) + if (tdb->format != 1) return 0; if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE) @@ -117,7 +124,7 @@ __TM_is_illegal (void* const tdb_ptr) { struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; - return (tdb->format == 0 + return (tdb->format == 1 && (tdb->abort_code == 4 /* unfiltered program interruption */ || tdb->abort_code == 11 /* restricted instruction */)); } @@ -127,7 +134,7 @@ __TM_is_footprint_exceeded (void* const tdb_ptr) { struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; - return (tdb->format == 0 + return (tdb->format == 1 && (tdb->abort_code == 7 /* fetch overflow */ || tdb->abort_code == 8 /* store overflow */)); } @@ -137,7 +144,7 @@ __TM_is_nested_too_deep (void* const tdb_ptr) { struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; - return tdb->format == 0 && tdb->abort_code == 13; /* depth exceeded */ + return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */ } extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -145,7 +152,7 @@ __TM_is_conflict (void* const tdb_ptr) { struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; - return (tdb->format == 0 + return (tdb->format == 1 && (tdb->abort_code == 9 /* fetch conflict */ || tdb->abort_code == 10 /* store conflict */)); } diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index cae4a32..62d162a 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -900,7 +900,8 @@ s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1, { /* For CCRAWmode put the required cc mask into the second operand. */ - if (GET_MODE (XVECEXP (*op0, 0, 0)) == CCRAWmode) + if (GET_MODE (XVECEXP (*op0, 0, 0)) == CCRAWmode + && INTVAL (*op1) >= 0 && INTVAL (*op1) <= 3) *op1 = gen_rtx_CONST_INT (VOIDmode, 1 << (3 - INTVAL (*op1))); *op0 = XVECEXP (*op0, 0, 0); *code = new_code; @@ -7973,6 +7974,9 @@ s390_optimize_nonescaping_tx (void) { bb = BASIC_BLOCK (bb_index); + if (!bb) + continue; + FOR_BB_INSNS (bb, insn) { rtx ite, cc, pat, target; @@ -8086,7 +8090,10 @@ s390_optimize_nonescaping_tx (void) if (!result) return; - PATTERN (tbegin_insn) = XVECEXP (PATTERN (tbegin_insn), 0, 0); + PATTERN (tbegin_insn) = gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, + XVECEXP (PATTERN (tbegin_insn), 0, 0), + XVECEXP (PATTERN (tbegin_insn), 0, 1))); INSN_CODE (tbegin_insn) = -1; df_insn_rescan (tbegin_insn); @@ -9798,6 +9805,7 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p) const int CC3 = 1 << 0; rtx abort_label = gen_label_rtx (); rtx leave_label = gen_label_rtx (); + rtx retry_plus_two = gen_reg_rtx (SImode); rtx retry_reg = gen_reg_rtx (SImode); rtx retry_label = NULL_RTX; rtx jump; @@ -9806,16 +9814,17 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p) if (retry != NULL_RTX) { emit_move_insn (retry_reg, retry); + emit_insn (gen_addsi3 (retry_plus_two, retry_reg, const2_rtx)); + emit_insn (gen_addsi3 (retry_reg, retry_reg, const1_rtx)); retry_label = gen_label_rtx (); emit_label (retry_label); } if (clobber_fprs_p) - emit_insn (gen_tbegin_1 (tdb, - gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK))); + emit_insn (gen_tbegin_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK), tdb)); else - emit_insn (gen_tbegin_nofloat_1 (tdb, - gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK))); + emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK), + tdb)); jump = s390_emit_jump (abort_label, gen_rtx_NE (VOIDmode, @@ -9836,6 +9845,10 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p) /* Abort handler code. */ emit_label (abort_label); + emit_move_insn (dest, gen_rtx_UNSPEC (SImode, + gen_rtvec (1, gen_rtx_REG (CCRAWmode, + CC_REGNUM)), + UNSPEC_CC_TO_INT)); if (retry != NULL_RTX) { rtx count = gen_reg_rtx (SImode); @@ -9847,7 +9860,7 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p) add_int_reg_note (jump, REG_BR_PROB, very_unlikely); /* CC2 - transient failure. Perform retry with ppa. */ - emit_move_insn (count, retry); + emit_move_insn (count, retry_plus_two); emit_insn (gen_subsi3 (count, count, retry_reg)); emit_insn (gen_tx_assist (count)); jump = emit_jump_insn (gen_doloop_si64 (retry_label, @@ -9857,10 +9870,6 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p) LABEL_NUSES (retry_label) = 1; } - emit_move_insn (dest, gen_rtx_UNSPEC (SImode, - gen_rtvec (1, gen_rtx_REG (CCRAWmode, - CC_REGNUM)), - UNSPEC_CC_TO_INT)); emit_label (leave_label); } @@ -9899,6 +9908,9 @@ static void s390_init_builtins (void) { tree ftype, uint64_type; + tree returns_twice_attr = tree_cons (get_identifier ("returns_twice"), + NULL, NULL); + tree noreturn_attr = tree_cons (get_identifier ("noreturn"), NULL, NULL); /* void foo (void) */ ftype = build_function_type_list (void_type_node, NULL_TREE); @@ -9909,17 +9921,17 @@ s390_init_builtins (void) ftype = build_function_type_list (void_type_node, integer_type_node, NULL_TREE); add_builtin_function ("__builtin_tabort", ftype, - S390_BUILTIN_TABORT, BUILT_IN_MD, NULL, NULL_TREE); + S390_BUILTIN_TABORT, BUILT_IN_MD, NULL, noreturn_attr); add_builtin_function ("__builtin_tx_assist", ftype, S390_BUILTIN_TX_ASSIST, BUILT_IN_MD, NULL, NULL_TREE); /* int foo (void *) */ ftype = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); add_builtin_function ("__builtin_tbegin", ftype, S390_BUILTIN_TBEGIN, - BUILT_IN_MD, NULL, NULL_TREE); + BUILT_IN_MD, NULL, returns_twice_attr); add_builtin_function ("__builtin_tbegin_nofloat", ftype, S390_BUILTIN_TBEGIN_NOFLOAT, - BUILT_IN_MD, NULL, NULL_TREE); + BUILT_IN_MD, NULL, returns_twice_attr); /* int foo (void *, int) */ ftype = build_function_type_list (integer_type_node, ptr_type_node, @@ -9927,11 +9939,11 @@ s390_init_builtins (void) add_builtin_function ("__builtin_tbegin_retry", ftype, S390_BUILTIN_TBEGIN_RETRY, BUILT_IN_MD, - NULL, NULL_TREE); + NULL, returns_twice_attr); add_builtin_function ("__builtin_tbegin_retry_nofloat", ftype, S390_BUILTIN_TBEGIN_RETRY_NOFLOAT, BUILT_IN_MD, - NULL, NULL_TREE); + NULL, returns_twice_attr); /* int foo (void) */ ftype = build_function_type_list (integer_type_node, NULL_TREE); diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 8354e26..d537d29 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -155,6 +155,7 @@ ; Transactional Execution support UNSPECV_TBEGIN + UNSPECV_TBEGIN_TDB UNSPECV_TBEGINC UNSPECV_TEND UNSPECV_TABORT @@ -9997,9 +9998,10 @@ (define_insn "tbegin_1" [(set (reg:CCRAW CC_REGNUM) - (unspec_volatile:CCRAW [(match_operand:BLK 0 "memory_operand" "=Q") - (match_operand 1 "const_int_operand" " D")] + (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")] UNSPECV_TBEGIN)) + (set (match_operand:BLK 1 "memory_operand" "=Q") + (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB)) (clobber (reg:DF 16)) (clobber (reg:DF 17)) (clobber (reg:DF 18)) @@ -10018,18 +10020,19 @@ (clobber (reg:DF 31))] ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is ; not supposed to be used for immediates (see genpreds.c). - "TARGET_HTM && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0xffff" - "tbegin\t%0,%x1" + "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff" + "tbegin\t%1,%x0" [(set_attr "op_type" "SIL")]) ; Same as above but without the FPR clobbers (define_insn "tbegin_nofloat_1" [(set (reg:CCRAW CC_REGNUM) - (unspec_volatile:CCRAW [(match_operand:BLK 0 "memory_operand" "=Q") - (match_operand 1 "const_int_operand" " D")] - UNSPECV_TBEGIN))] - "TARGET_HTM && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0xffff" - "tbegin\t%0,%x1" + (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")] + UNSPECV_TBEGIN)) + (set (match_operand:BLK 1 "memory_operand" "=Q") + (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))] + "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff" + "tbegin\t%1,%x0" [(set_attr "op_type" "SIL")]) @@ -10113,15 +10116,12 @@ ; Transaction perform processor assist (define_expand "tx_assist" - [(set (match_dup 1) (const_int 0)) - (unspec_volatile [(match_operand:SI 0 "register_operand" "") - (match_dup 1) + [(unspec_volatile [(match_operand:SI 0 "register_operand" "") + (reg:SI GPR0_REGNUM) (const_int 1)] UNSPECV_PPA)] "TARGET_HTM" -{ - operands[1] = gen_reg_rtx (SImode); -}) + "") (define_insn "*ppa" [(unspec_volatile [(match_operand:SI 0 "register_operand" "d") @@ -10129,5 +10129,5 @@ (match_operand 2 "const_int_operand" "I")] UNSPECV_PPA)] "TARGET_HTM && INTVAL (operands[2]) < 16" - "ppa\t%0,%1,1" + "ppa\t%0,%1,%2" [(set_attr "op_type" "RRF")]) |