aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/config/s390
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/config/s390')
-rw-r--r--gcc-4.8/gcc/config/s390/htmxlintrin.h25
-rw-r--r--gcc-4.8/gcc/config/s390/s390-protos.h1
-rw-r--r--gcc-4.8/gcc/config/s390/s390.c302
-rw-r--r--gcc-4.8/gcc/config/s390/s390.h5
-rw-r--r--gcc-4.8/gcc/config/s390/s390.md32
-rw-r--r--gcc-4.8/gcc/config/s390/s390.opt8
6 files changed, 295 insertions, 78 deletions
diff --git a/gcc-4.8/gcc/config/s390/htmxlintrin.h b/gcc-4.8/gcc/config/s390/htmxlintrin.h
index bb142195b..952b40975 100644
--- a/gcc-4.8/gcc/config/s390/htmxlintrin.h
+++ b/gcc-4.8/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" publically 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-4.8/gcc/config/s390/s390-protos.h b/gcc-4.8/gcc/config/s390/s390-protos.h
index 67283df45..7b43ed01b 100644
--- a/gcc-4.8/gcc/config/s390/s390-protos.h
+++ b/gcc-4.8/gcc/config/s390/s390-protos.h
@@ -110,5 +110,6 @@ extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *);
extern int s390_branch_condition_mask (rtx);
extern int s390_compare_and_branch_condition_mask (rtx);
extern bool s390_extzv_shift_ok (int, int, unsigned HOST_WIDE_INT);
+extern void s390_asm_output_function_label (FILE *, const char *, tree);
#endif /* RTX_CODE */
diff --git a/gcc-4.8/gcc/config/s390/s390.c b/gcc-4.8/gcc/config/s390/s390.c
index 273022778..836a3d4fd 100644
--- a/gcc-4.8/gcc/config/s390/s390.c
+++ b/gcc-4.8/gcc/config/s390/s390.c
@@ -407,6 +407,65 @@ struct GTY(()) machine_function
bytes on a z10 (or higher) CPU. */
#define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048)
+static const int s390_hotpatch_trampoline_halfwords_default = 12;
+static const int s390_hotpatch_trampoline_halfwords_max = 1000000;
+static int s390_hotpatch_trampoline_halfwords = -1;
+
+/* Return the argument of the given hotpatch attribute or the default value if
+ no argument is present. */
+
+static inline int
+get_hotpatch_attribute (tree hotpatch_attr)
+{
+ const_tree args;
+
+ args = TREE_VALUE (hotpatch_attr);
+
+ return (args) ?
+ TREE_INT_CST_LOW (TREE_VALUE (args)):
+ s390_hotpatch_trampoline_halfwords_default;
+}
+
+/* Check whether the hotpatch attribute is applied to a function and, if it has
+ an argument, the argument is valid. */
+
+static tree
+s390_handle_hotpatch_attribute (tree *node, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute only applies to functions",
+ name);
+ *no_add_attrs = true;
+ }
+ else if (args)
+ {
+ tree expr = TREE_VALUE (args);
+
+ if (TREE_CODE (expr) != INTEGER_CST
+ || !INTEGRAL_TYPE_P (TREE_TYPE (expr))
+ || TREE_INT_CST_HIGH (expr) != 0
+ || TREE_INT_CST_LOW (expr) > (unsigned int)
+ s390_hotpatch_trampoline_halfwords_max)
+ {
+ error ("requested %qE attribute is not a non-negative integer"
+ " constant or too large (max. %d)", name,
+ s390_hotpatch_trampoline_halfwords_max);
+ *no_add_attrs = true;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+static const struct attribute_spec s390_attribute_table[] = {
+ { "hotpatch", 0, 1, true, false, false, s390_handle_hotpatch_attribute, false
+ },
+ /* End element. */
+ { NULL, 0, 0, false, false, false, NULL, false }
+};
+
/* Return the alignment for LABEL. We default to the -falign-labels
value except for the literal pool base label. */
int
@@ -883,7 +942,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;
@@ -1594,6 +1654,46 @@ s390_init_machine_status (void)
static void
s390_option_override (void)
{
+ unsigned int i;
+ cl_deferred_option *opt;
+ vec<cl_deferred_option> *v =
+ (vec<cl_deferred_option> *) s390_deferred_options;
+
+ if (v)
+ FOR_EACH_VEC_ELT (*v, i, opt)
+ {
+ switch (opt->opt_index)
+ {
+ case OPT_mhotpatch:
+ s390_hotpatch_trampoline_halfwords = (opt->value) ?
+ s390_hotpatch_trampoline_halfwords_default : -1;
+ break;
+ case OPT_mhotpatch_:
+ {
+ int val;
+
+ val = integral_argument (opt->arg);
+ if (val == -1)
+ {
+ /* argument is not a plain number */
+ error ("argument to %qs should be a non-negative integer",
+ "-mhotpatch=");
+ break;
+ }
+ else if (val > s390_hotpatch_trampoline_halfwords_max)
+ {
+ error ("argument to %qs is too large (max. %d)",
+ "-mhotpatch=", s390_hotpatch_trampoline_halfwords_max);
+ break;
+ }
+ s390_hotpatch_trampoline_halfwords = val;
+ break;
+ }
+ default:
+ gcc_unreachable ();
+ }
+ }
+
/* Set up function hooks. */
init_machine_status = s390_init_machine_status;
@@ -3015,15 +3115,22 @@ s390_preferred_reload_class (rtx op, reg_class_t rclass)
prefer ADDR_REGS. If 'class' is not a superset
of ADDR_REGS, e.g. FP_REGS, reject this reload. */
case CONST:
- /* A larl operand with odd addend will get fixed via secondary
- reload. So don't request it to be pushed into literal
- pool. */
+ /* Symrefs cannot be pushed into the literal pool with -fPIC
+ so we *MUST NOT* return NO_REGS for these cases
+ (s390_cannot_force_const_mem will return true).
+
+ On the other hand we MUST return NO_REGS for symrefs with
+ invalid addend which might have been pushed to the literal
+ pool (no -fPIC). Usually we would expect them to be
+ handled via secondary reload but this does not happen if
+ they are used as literal pool slot replacement in reload
+ inheritance (see emit_input_reload_insns). */
if (TARGET_CPU_ZARCH
&& GET_CODE (XEXP (op, 0)) == PLUS
&& GET_CODE (XEXP (XEXP(op, 0), 0)) == SYMBOL_REF
&& GET_CODE (XEXP (XEXP(op, 0), 1)) == CONST_INT)
{
- if (reg_class_subset_p (ADDR_REGS, rclass))
+ if (flag_pic && reg_class_subset_p (ADDR_REGS, rclass))
return ADDR_REGS;
else
return NO_REGS;
@@ -4683,7 +4790,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
int smode_bsize, mode_bsize;
rtx op, clobber;
- if (bitsize + bitpos > GET_MODE_SIZE (mode))
+ if (bitsize + bitpos > GET_MODE_BITSIZE (mode))
return false;
/* Generate INSERT IMMEDIATE (IILL et al). */
@@ -5311,6 +5418,101 @@ get_some_local_dynamic_name (void)
gcc_unreachable ();
}
+/* Returns -1 if the function should not be made hotpatchable. Otherwise it
+ returns a number >= 0 that is the desired size of the hotpatch trampoline
+ in halfwords. */
+
+static int s390_function_num_hotpatch_trampoline_halfwords (tree decl,
+ bool do_warn)
+{
+ tree attr;
+
+ if (DECL_DECLARED_INLINE_P (decl)
+ || DECL_ARTIFICIAL (decl)
+ || MAIN_NAME_P (DECL_NAME (decl)))
+ {
+ /* - Explicitly inlined functions cannot be hotpatched.
+ - Artificial functions need not be hotpatched.
+ - Making the main function hotpatchable is useless. */
+ return -1;
+ }
+ attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl));
+ if (attr || s390_hotpatch_trampoline_halfwords >= 0)
+ {
+ if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)))
+ {
+ if (do_warn)
+ warning (OPT_Wattributes, "function %qE with the %qs attribute"
+ " is not hotpatchable", DECL_NAME (decl), "always_inline");
+ return -1;
+ }
+ else
+ {
+ return (attr) ?
+ get_hotpatch_attribute (attr) : s390_hotpatch_trampoline_halfwords;
+ }
+ }
+
+ return -1;
+}
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+s390_can_inline_p (tree caller, tree callee)
+{
+ if (s390_function_num_hotpatch_trampoline_halfwords (callee, false) >= 0)
+ return false;
+
+ return default_target_can_inline_p (caller, callee);
+}
+
+/* Write the extra assembler code needed to declare a function properly. */
+
+void
+s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
+ tree decl)
+{
+ int hotpatch_trampoline_halfwords = -1;
+
+ if (decl)
+ {
+ hotpatch_trampoline_halfwords =
+ s390_function_num_hotpatch_trampoline_halfwords (decl, true);
+ if (hotpatch_trampoline_halfwords >= 0
+ && decl_function_context (decl) != NULL_TREE)
+ {
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_mhotpatch,
+ "hotpatching is not compatible with nested functions");
+ hotpatch_trampoline_halfwords = -1;
+ }
+ }
+
+ if (hotpatch_trampoline_halfwords > 0)
+ {
+ int i;
+
+ /* Add a trampoline code area before the function label and initialize it
+ with two-byte nop instructions. This area can be overwritten with code
+ that jumps to a patched version of the function. */
+ for (i = 0; i < hotpatch_trampoline_halfwords; i++)
+ asm_fprintf (asm_out_file, "\tnopr\t%%r7\n");
+ /* Note: The function label must be aligned so that (a) the bytes of the
+ following nop do not cross a cacheline boundary, and (b) a jump address
+ (eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be
+ stored directly before the label without crossing a cacheline
+ boundary. All this is necessary to make sure the trampoline code can
+ be changed atomically. */
+ }
+
+ ASM_OUTPUT_LABEL (asm_out_file, fname);
+
+ /* Output a four-byte nop if hotpatching is enabled. This can be overwritten
+ atomically with a relative backwards jump to the trampoline area. */
+ if (hotpatch_trampoline_halfwords >= 0)
+ asm_fprintf (asm_out_file, "\tnop\t0\n");
+}
+
/* Output machine-dependent UNSPECs occurring in address constant X
in assembler syntax to stdio stream FILE. Returns true if the
constant X could be recognized, false otherwise. */
@@ -7846,6 +8048,9 @@ s390_optimize_nonescaping_tx (void)
{
bb = BASIC_BLOCK (bb_index);
+ if (!bb)
+ continue;
+
FOR_BB_INSNS (bb, insn)
{
rtx ite, cc, pat, target;
@@ -7959,7 +8164,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);
@@ -9568,61 +9776,47 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
void
s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
{
- const int CC0 = 1 << 3;
- const int CC1 = 1 << 2;
- 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;
- rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
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)));
-
- jump = s390_emit_jump (abort_label,
- gen_rtx_NE (VOIDmode,
- gen_rtx_REG (CCRAWmode, CC_REGNUM),
- gen_rtx_CONST_INT (VOIDmode, CC0)));
-
- JUMP_LABEL (jump) = abort_label;
- LABEL_NUSES (abort_label) = 1;
- add_reg_note (jump, REG_BR_PROB, very_unlikely);
+ emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
+ tdb));
- /* Initialize CC return value. */
- emit_move_insn (dest, const0_rtx);
-
- s390_emit_jump (leave_label, NULL_RTX);
- LABEL_NUSES (leave_label) = 1;
- emit_barrier ();
-
- /* 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)
{
+ const int CC0 = 1 << 3;
+ const int CC1 = 1 << 2;
+ const int CC3 = 1 << 0;
+ rtx jump;
rtx count = gen_reg_rtx (SImode);
+ rtx leave_label = gen_label_rtx ();
+
+ /* Exit for success and permanent failures. */
jump = s390_emit_jump (leave_label,
gen_rtx_EQ (VOIDmode,
gen_rtx_REG (CCRAWmode, CC_REGNUM),
- gen_rtx_CONST_INT (VOIDmode, CC1 | CC3)));
- LABEL_NUSES (leave_label) = 2;
- add_reg_note (jump, REG_BR_PROB, very_unlikely);
+ gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3)));
+ LABEL_NUSES (leave_label) = 1;
/* 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,
@@ -9630,13 +9824,8 @@ s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
retry_reg));
JUMP_LABEL (jump) = retry_label;
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);
+ }
}
/* Builtins. */
@@ -9674,6 +9863,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);
@@ -9684,17 +9876,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,
@@ -9702,11 +9894,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);
@@ -11622,6 +11814,12 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
#undef TARGET_CANONICALIZE_COMPARISON
#define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
+#undef TARGET_ATTRIBUTE_TABLE
+#define TARGET_ATTRIBUTE_TABLE s390_attribute_table
+
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P s390_can_inline_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h"
diff --git a/gcc-4.8/gcc/config/s390/s390.h b/gcc-4.8/gcc/config/s390/s390.h
index 03ab89000..a937c30d2 100644
--- a/gcc-4.8/gcc/config/s390/s390.h
+++ b/gcc-4.8/gcc/config/s390/s390.h
@@ -217,7 +217,7 @@ enum processor_flags
#define STACK_BOUNDARY 64
/* Allocation boundary (in *bits*) for the code of a function. */
-#define FUNCTION_BOUNDARY 32
+#define FUNCTION_BOUNDARY 64
/* There is no point aligning anything to a rounder boundary than this. */
#define BIGGEST_ALIGNMENT 64
@@ -878,6 +878,9 @@ do { \
fputc ('\n', (FILE)); \
} while (0)
+#undef ASM_OUTPUT_FUNCTION_LABEL
+#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \
+ s390_asm_output_function_label (FILE, NAME, DECL)
/* Miscellaneous parameters. */
diff --git a/gcc-4.8/gcc/config/s390/s390.md b/gcc-4.8/gcc/config/s390/s390.md
index ad3ba27c5..fab189843 100644
--- a/gcc-4.8/gcc/config/s390/s390.md
+++ b/gcc-4.8/gcc/config/s390/s390.md
@@ -147,6 +147,7 @@
; Transactional Execution support
UNSPECV_TBEGIN
+ UNSPECV_TBEGIN_TDB
UNSPECV_TBEGINC
UNSPECV_TEND
UNSPECV_TABORT
@@ -9896,9 +9897,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))
@@ -9917,18 +9919,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")])
@@ -10012,15 +10015,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")
@@ -10028,5 +10028,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")])
diff --git a/gcc-4.8/gcc/config/s390/s390.opt b/gcc-4.8/gcc/config/s390/s390.opt
index a4e6ef25d..65d17c334 100644
--- a/gcc-4.8/gcc/config/s390/s390.opt
+++ b/gcc-4.8/gcc/config/s390/s390.opt
@@ -96,6 +96,14 @@ mhard-float
Target Report RejectNegative Negative(msoft-float) InverseMask(SOFT_FLOAT, HARD_FLOAT)
Enable hardware floating point
+mhotpatch
+Target Report Var(s390_deferred_options) Defer
+Prepend the function label with 12 two-byte Nop instructions, and add a four byte Nop instruction after the label for hotpatching.
+
+mhotpatch=
+Target RejectNegative Report Joined Var(s390_deferred_options) Defer
+Prepend the function label with the given number of two-byte Nop instructions, and add a four byte Nop instruction after the label for hotpatching.
+
mlong-double-128
Target Report RejectNegative Negative(mlong-double-64) Mask(LONG_DOUBLE_128)
Use 128-bit long double