summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-17 14:11:09 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-17 14:11:09 +0000
commitefd91cd30792a75763e7421132d49659951c1086 (patch)
treed899e8c317ec72f3f4b89c740d60b0fe1c5af02f /gcc/config
parent6e52f3a56b6df129f8ab380725d8bcb57d9c6df8 (diff)
downloadgcc-efd91cd30792a75763e7421132d49659951c1086.tar.gz
2013-07-17 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 201008 using svnmerge.py git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@201009 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/aarch64/aarch64-protos.h15
-rw-r--r--gcc/config/aarch64/aarch64.c42
-rw-r--r--gcc/config/aarch64/aarch64.md11
-rw-r--r--gcc/config/arm/arm.c12
-rw-r--r--gcc/config/mips/mips.c8
-rw-r--r--gcc/config/mips/mips.h29
-rw-r--r--gcc/config/mips/mips.md16
-rw-r--r--gcc/config/rl78/constraints.md13
-rw-r--r--gcc/config/rs6000/htm.md366
-rw-r--r--gcc/config/rs6000/htmintrin.h131
-rw-r--r--gcc/config/rs6000/htmxlintrin.h208
-rw-r--r--gcc/config/rs6000/predicates.md37
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def86
-rw-r--r--gcc/config/rs6000/rs6000-c.c2
-rw-r--r--gcc/config/rs6000/rs6000-cpus.def2
-rw-r--r--gcc/config/rs6000/rs6000.c350
-rw-r--r--gcc/config/rs6000/rs6000.h50
-rw-r--r--gcc/config/rs6000/rs6000.md6
-rw-r--r--gcc/config/rs6000/rs6000.opt4
-rw-r--r--gcc/config/rs6000/t-rs60001
-rw-r--r--gcc/config/s390/s390.c7
-rw-r--r--gcc/config/s390/s390.h3
22 files changed, 1325 insertions, 74 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index a024bd2ed2d..f19045d0792 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -75,6 +75,17 @@ enum aarch64_symbol_context
ADR x0, foo
+ SYMBOL_TINY_GOT
+
+ Generate symbol accesses via the GOT using a single PC relative
+ instruction. To compute the address of symbol foo, we generate:
+
+ ldr t0, :got:foo
+
+ The value of foo can subsequently read using:
+
+ ldrb t0, [t0]
+
SYMBOL_FORCE_TO_MEM : Global variables are addressed using
constant pool. All variable addresses are spilled into constant
pools. The constant pools themselves are addressed using PC
@@ -89,6 +100,7 @@ enum aarch64_symbol_type
SYMBOL_SMALL_GOTTPREL,
SYMBOL_SMALL_TPREL,
SYMBOL_TINY_ABSOLUTE,
+ SYMBOL_TINY_GOT,
SYMBOL_FORCE_TO_MEM
};
@@ -204,9 +216,6 @@ int aarch64_asm_preferred_eh_data_format (int, int);
int aarch64_hard_regno_mode_ok (unsigned, enum machine_mode);
int aarch64_hard_regno_nregs (unsigned, enum machine_mode);
int aarch64_simd_attr_length_move (rtx);
-int aarch64_simd_immediate_valid_for_move (rtx, enum machine_mode, rtx *,
- int *, unsigned char *, int *,
- int *);
int aarch64_uxt_size (int, HOST_WIDE_INT);
rtx aarch64_final_eh_return_addr (void);
rtx aarch64_legitimize_reload_address (rtx *, enum machine_mode, int, int, int);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 4ba46d215d7..a97f6ae06d2 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -95,6 +95,7 @@ struct simd_immediate_info
int shift;
int element_width;
bool mvn;
+ bool msl;
};
/* The current code model. */
@@ -612,6 +613,10 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
return;
}
+ case SYMBOL_TINY_GOT:
+ emit_insn (gen_ldr_got_tiny (dest, imm));
+ return;
+
default:
gcc_unreachable ();
}
@@ -889,6 +894,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
case SYMBOL_SMALL_TLSDESC:
case SYMBOL_SMALL_GOTTPREL:
case SYMBOL_SMALL_GOT:
+ case SYMBOL_TINY_GOT:
if (offset != const0_rtx)
{
gcc_assert(can_create_pseudo_p ());
@@ -3645,6 +3651,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (asm_out_file, ":tprel:");
break;
+ case SYMBOL_TINY_GOT:
+ gcc_unreachable ();
+ break;
+
default:
break;
}
@@ -3674,6 +3684,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
break;
+ case SYMBOL_TINY_GOT:
+ asm_fprintf (asm_out_file, ":got:");
+ break;
+
default:
break;
}
@@ -5240,7 +5254,7 @@ aarch64_classify_symbol (rtx x,
case AARCH64_CMODEL_TINY_PIC:
if (!aarch64_symbol_binds_local_p (x))
- return SYMBOL_SMALL_GOT;
+ return SYMBOL_TINY_GOT;
return SYMBOL_TINY_ABSOLUTE;
case AARCH64_CMODEL_SMALL_PIC:
@@ -6437,16 +6451,16 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1], 8, 1);
CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0 && bytes[i + 3] == 0, 0, 0);
+ && bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 0, 1);
+ && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 0, 0);
+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 0, 1);
+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0);
@@ -6455,12 +6469,7 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
}
while (0);
- /* TODO: Currently the assembler cannot handle types 12 to 15.
- And there is no way to specify cmode through the compiler.
- Disable them till there is support in the assembler. */
- if (immtype == -1
- || (immtype >= 12 && immtype <= 15)
- || immtype == 18)
+ if (immtype == -1)
return false;
if (info)
@@ -6471,6 +6480,9 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
unsigned HOST_WIDE_INT imm = 0;
+ if (immtype >= 12 && immtype <= 15)
+ info->msl = true;
+
/* Un-invert bytes of recognized vector, if necessary. */
if (invmask != 0)
for (i = 0; i < idx; i++)
@@ -7403,10 +7415,11 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
bool is_valid;
static char templ[40];
const char *mnemonic;
+ const char *shift_op;
unsigned int lane_count = 0;
char element_char;
- struct simd_immediate_info info;
+ struct simd_immediate_info info = { NULL_RTX, 0, 0, false, false };
/* This will return true to show const_vector is legal for use as either
a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will
@@ -7442,14 +7455,15 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
}
mnemonic = info.mvn ? "mvni" : "movi";
+ shift_op = info.msl ? "msl" : "lsl";
if (lane_count == 1)
snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
mnemonic, UINTVAL (info.value));
else if (info.shift)
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX
- ", lsl %d", mnemonic, lane_count, element_char,
- UINTVAL (info.value), info.shift);
+ ", %s %d", mnemonic, lane_count, element_char,
+ UINTVAL (info.value), shift_op, info.shift);
else
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX,
mnemonic, lane_count, element_char, UINTVAL (info.value));
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 68336db0ed5..229564cc962 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -80,6 +80,7 @@
UNSPEC_FRINTZ
UNSPEC_GOTSMALLPIC
UNSPEC_GOTSMALLTLS
+ UNSPEC_GOTTINYPIC
UNSPEC_LD2
UNSPEC_LD3
UNSPEC_LD4
@@ -3751,6 +3752,16 @@
(set_attr "mode" "DI")]
)
+(define_insn "ldr_got_tiny"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
+ UNSPEC_GOTTINYPIC))]
+ ""
+ "ldr\\t%0, %L1"
+ [(set_attr "v8type" "load1")
+ (set_attr "mode" "DI")]
+)
+
(define_insn "aarch64_load_tp_hard"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(const_int 0)] UNSPEC_TLS))]
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index e6fd42079cb..35096e83b20 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -12018,8 +12018,16 @@ gen_movmem_ldrd_strd (rtx *operands)
dst = adjust_address (dst, HImode, 0);
src = adjust_address (src, HImode, 0);
reg0 = gen_reg_rtx (SImode);
- emit_insn (gen_unaligned_loadhiu (reg0, src));
- emit_insn (gen_unaligned_storehi (dst, gen_lowpart (HImode, reg0)));
+ if (src_aligned)
+ emit_insn (gen_zero_extendhisi2 (reg0, src));
+ else
+ emit_insn (gen_unaligned_loadhiu (reg0, src));
+
+ if (dst_aligned)
+ emit_insn (gen_movhi (dst, gen_lowpart(HImode, reg0)));
+ else
+ emit_insn (gen_unaligned_storehi (dst, gen_lowpart (HImode, reg0)));
+
src = next_consecutive_mem (src);
dst = next_consecutive_mem (dst);
if (len == 2)
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 3c7e4391014..e95bdd88d4a 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -3857,7 +3857,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
case MINUS:
if (float_mode_p
- && (ISA_HAS_NMADD4_NMSUB4 (mode) || ISA_HAS_NMADD3_NMSUB3 (mode))
+ && (ISA_HAS_NMADD4_NMSUB4 || ISA_HAS_NMADD3_NMSUB3)
&& TARGET_FUSED_MADD
&& !HONOR_NANS (mode)
&& !HONOR_SIGNED_ZEROS (mode))
@@ -3890,7 +3890,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
{
/* If this is part of a MADD or MSUB, treat the PLUS as
being free. */
- if (ISA_HAS_FP4
+ if ((ISA_HAS_FP_MADD4_MSUB4 || ISA_HAS_FP_MADD3_MSUB3)
&& TARGET_FUSED_MADD
&& GET_CODE (XEXP (x, 0)) == MULT)
*total = 0;
@@ -3909,7 +3909,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
case NEG:
if (float_mode_p
- && (ISA_HAS_NMADD4_NMSUB4 (mode) || ISA_HAS_NMADD3_NMSUB3 (mode))
+ && (ISA_HAS_NMADD4_NMSUB4 || ISA_HAS_NMADD3_NMSUB3)
&& TARGET_FUSED_MADD
&& !HONOR_NANS (mode)
&& HONOR_SIGNED_ZEROS (mode))
@@ -6899,7 +6899,7 @@ mips_expand_call (enum mips_call_type type, rtx result, rtx addr,
gcc_assert (!lazy_p && type == MIPS_CALL_NORMAL);
return insn;
}
- ;
+
orig_addr = addr;
if (!call_insn_operand (addr, VOIDmode))
{
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index d775a8c940b..007f598c658 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -873,7 +873,7 @@ struct mips_cpu_info {
FP madd and msub instructions, and the FP recip and recip sqrt
instructions. */
#define ISA_HAS_FP4 ((ISA_MIPS4 \
- || (ISA_MIPS32R2 && TARGET_FLOAT64) \
+ || (ISA_MIPS32R2 && TARGET_FLOAT64) \
|| ISA_MIPS64 \
|| ISA_MIPS64R2) \
&& !TARGET_MIPS16)
@@ -895,25 +895,20 @@ struct mips_cpu_info {
#define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16)
/* ISA has floating-point madd and msub instructions 'd = a * b [+-] c'. */
-#define ISA_HAS_FP_MADD4_MSUB4 ISA_HAS_FP4
+#define ISA_HAS_FP_MADD4_MSUB4 (ISA_HAS_FP4 \
+ || (ISA_MIPS32R2 && !TARGET_MIPS16))
/* ISA has floating-point madd and msub instructions 'c = a * b [+-] c'. */
#define ISA_HAS_FP_MADD3_MSUB3 TARGET_LOONGSON_2EF
/* ISA has floating-point nmadd and nmsub instructions
'd = -((a * b) [+-] c)'. */
-#define ISA_HAS_NMADD4_NMSUB4(MODE) \
- ((ISA_MIPS4 \
- || (ISA_MIPS32R2 && (MODE) == V2SFmode) \
- || ISA_MIPS64 \
- || ISA_MIPS64R2) \
- && (!TARGET_MIPS5400 || TARGET_MAD) \
- && !TARGET_MIPS16)
+#define ISA_HAS_NMADD4_NMSUB4 (ISA_HAS_FP4 \
+ || (ISA_MIPS32R2 && !TARGET_MIPS16))
/* ISA has floating-point nmadd and nmsub instructions
'c = -((a * b) [+-] c)'. */
-#define ISA_HAS_NMADD3_NMSUB3(MODE) \
- TARGET_LOONGSON_2EF
+#define ISA_HAS_NMADD3_NMSUB3 TARGET_LOONGSON_2EF
/* ISA has count leading zeroes/ones instruction (not implemented). */
#define ISA_HAS_CLZ_CLO ((ISA_MIPS32 \
@@ -929,22 +924,22 @@ struct mips_cpu_info {
|| TARGET_SR71K) \
&& !TARGET_MIPS16)
-/* ISA has three operand multiply instructions that
- negates the result and puts the result in an accumulator. */
+/* ISA has three operand multiply instructions that negate the
+ result and put the result in an accumulator. */
#define ISA_HAS_MULS ((TARGET_MIPS5400 \
|| TARGET_MIPS5500 \
|| TARGET_SR71K) \
&& !TARGET_MIPS16)
-/* ISA has three operand multiply instructions that subtracts the
- result from a 4th operand and puts the result in an accumulator. */
+/* ISA has three operand multiply instructions that subtract the
+ result from a 4th operand and put the result in an accumulator. */
#define ISA_HAS_MSAC ((TARGET_MIPS5400 \
|| TARGET_MIPS5500 \
|| TARGET_SR71K) \
&& !TARGET_MIPS16)
-/* ISA has three operand multiply instructions that the result
- from a 4th operand and puts the result in an accumulator. */
+/* ISA has three operand multiply instructions that add the result
+ to a 4th operand and put the result in an accumulator. */
#define ISA_HAS_MACC ((TARGET_MIPS4120 \
|| TARGET_MIPS4130 \
|| TARGET_MIPS5400 \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index b832dda27f0..ca79a31e29a 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -2367,7 +2367,7 @@
(mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "f"))))]
- "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -2382,7 +2382,7 @@
(mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "0"))))]
- "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ "ISA_HAS_NMADD3_NMSUB3
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -2397,7 +2397,7 @@
(mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "f")))]
- "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -2412,7 +2412,7 @@
(mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "0")))]
- "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ "ISA_HAS_NMADD3_NMSUB3
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -2427,7 +2427,7 @@
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f"))
(match_operand:ANYF 1 "register_operand" "f"))))]
- "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -2442,7 +2442,7 @@
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f"))
(match_operand:ANYF 1 "register_operand" "0"))))]
- "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ "ISA_HAS_NMADD3_NMSUB3
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -2457,7 +2457,7 @@
(match_operand:ANYF 1 "register_operand" "f")
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f"))))]
- "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
+ "ISA_HAS_NMADD4_NMSUB4
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
@@ -2472,7 +2472,7 @@
(match_operand:ANYF 1 "register_operand" "f")
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "0"))))]
- "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
+ "ISA_HAS_NMADD3_NMSUB3
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)
&& !HONOR_NANS (<MODE>mode)"
diff --git a/gcc/config/rl78/constraints.md b/gcc/config/rl78/constraints.md
index 01aff39b11f..8b03cf32211 100644
--- a/gcc/config/rl78/constraints.md
+++ b/gcc/config/rl78/constraints.md
@@ -256,6 +256,19 @@
(match_test "!rl78_far_p (op) && rl78_as_legitimate_address (VOIDmode, XEXP (op, 0), true, ADDR_SPACE_GENERIC)"))
)
+(define_memory_constraint "U"
+ "memory references valid with mov to/from a/ax"
+ (and (match_code "mem")
+ (match_test "rl78_virt_insns_ok ()
+|| satisfies_constraint_Wab (op)
+|| satisfies_constraint_Wbc (op)
+|| satisfies_constraint_Wde (op)
+|| satisfies_constraint_Wd2 (op)
+|| satisfies_constraint_Whl (op)
+|| satisfies_constraint_Wh1 (op)
+|| satisfies_constraint_Whb (op)
+|| satisfies_constraint_Ws1 (op)
+|| satisfies_constraint_Wfr (op) ")))
(define_memory_constraint "Qbi"
"built-in compare types"
diff --git a/gcc/config/rs6000/htm.md b/gcc/config/rs6000/htm.md
new file mode 100644
index 00000000000..e8ec91aef71
--- /dev/null
+++ b/gcc/config/rs6000/htm.md
@@ -0,0 +1,366 @@
+;; Hardware Transactional Memory (HTM) patterns.
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+;; Contributed by Peter Bergner <bergner@vnet.ibm.com>.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_constants
+ [(TFHAR_SPR 128)
+ (TFIAR_SPR 129)
+ (TEXASR_SPR 130)
+ (TEXASRU_SPR 131)
+ (MAX_HTM_OPERANDS 4)
+ ])
+
+;;
+;; UNSPEC_VOLATILE usage
+;;
+
+(define_c_enum "unspecv"
+ [UNSPECV_HTM_TABORT
+ UNSPECV_HTM_TABORTDC
+ UNSPECV_HTM_TABORTDCI
+ UNSPECV_HTM_TABORTWC
+ UNSPECV_HTM_TABORTWCI
+ UNSPECV_HTM_TBEGIN
+ UNSPECV_HTM_TCHECK
+ UNSPECV_HTM_TEND
+ UNSPECV_HTM_TRECHKPT
+ UNSPECV_HTM_TRECLAIM
+ UNSPECV_HTM_TSR
+ UNSPECV_HTM_MFSPR
+ UNSPECV_HTM_MTSPR
+ ])
+
+
+(define_expand "tabort"
+ [(set (match_dup 2)
+ (unspec_volatile:CC [(match_operand:SI 1 "int_reg_operand" "")]
+ UNSPECV_HTM_TABORT))
+ (set (match_dup 3)
+ (eq:SI (match_dup 2)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 3)))]
+ "TARGET_HTM"
+{
+ operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tabort_internal"
+ [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand:SI 0 "int_reg_operand" "r")]
+ UNSPECV_HTM_TABORT))]
+ "TARGET_HTM"
+ "tabort. %0"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tabortdc"
+ [(set (match_dup 4)
+ (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n")
+ (match_operand:SI 2 "gpc_reg_operand" "r")
+ (match_operand:SI 3 "gpc_reg_operand" "r")]
+ UNSPECV_HTM_TABORTDC))
+ (set (match_dup 5)
+ (eq:SI (match_dup 4)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 5)))]
+ "TARGET_HTM"
+{
+ operands[4] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[5] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tabortdc_internal"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
+ (match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:SI 2 "gpc_reg_operand" "r")]
+ UNSPECV_HTM_TABORTDC))]
+ "TARGET_HTM"
+ "tabortdc. %0,%1,%2"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tabortdci"
+ [(set (match_dup 4)
+ (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n")
+ (match_operand:SI 2 "gpc_reg_operand" "r")
+ (match_operand 3 "s5bit_cint_operand" "n")]
+ UNSPECV_HTM_TABORTDCI))
+ (set (match_dup 5)
+ (eq:SI (match_dup 4)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 5)))]
+ "TARGET_HTM"
+{
+ operands[4] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[5] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tabortdci_internal"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
+ (match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand 2 "s5bit_cint_operand" "n")]
+ UNSPECV_HTM_TABORTDCI))]
+ "TARGET_HTM"
+ "tabortdci. %0,%1,%2"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tabortwc"
+ [(set (match_dup 4)
+ (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n")
+ (match_operand:SI 2 "gpc_reg_operand" "r")
+ (match_operand:SI 3 "gpc_reg_operand" "r")]
+ UNSPECV_HTM_TABORTWC))
+ (set (match_dup 5)
+ (eq:SI (match_dup 4)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 5)))]
+ "TARGET_HTM"
+{
+ operands[4] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[5] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tabortwc_internal"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
+ (match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:SI 2 "gpc_reg_operand" "r")]
+ UNSPECV_HTM_TABORTWC))]
+ "TARGET_HTM"
+ "tabortwc. %0,%1,%2"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tabortwci"
+ [(set (match_dup 4)
+ (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n")
+ (match_operand:SI 2 "gpc_reg_operand" "r")
+ (match_operand 3 "s5bit_cint_operand" "n")]
+ UNSPECV_HTM_TABORTWCI))
+ (set (match_dup 5)
+ (eq:SI (match_dup 4)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 5)))]
+ "TARGET_HTM"
+{
+ operands[4] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[5] = gen_reg_rtx (SImode);
+})
+
+(define_expand "ttest"
+ [(set (match_dup 1)
+ (unspec_volatile:CC [(const_int 0)
+ (reg:SI 0)
+ (const_int 0)]
+ UNSPECV_HTM_TABORTWCI))
+ (set (subreg:CC (match_dup 2) 0) (match_dup 1))
+ (set (match_dup 3) (lshiftrt:SI (match_dup 2) (const_int 24)))
+ (parallel [(set (match_operand:SI 0 "int_reg_operand" "")
+ (and:SI (match_dup 3) (const_int 15)))
+ (clobber (scratch:CC))])]
+ "TARGET_HTM"
+{
+ operands[1] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[2] = gen_reg_rtx (SImode);
+ operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tabortwci_internal"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
+ (match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand 2 "s5bit_cint_operand" "n")]
+ UNSPECV_HTM_TABORTWCI))]
+ "TARGET_HTM"
+ "tabortwci. %0,%1,%2"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tbegin"
+ [(set (match_dup 2)
+ (unspec_volatile:CC [(match_operand 1 "const_0_to_1_operand" "n")]
+ UNSPECV_HTM_TBEGIN))
+ (set (match_dup 3)
+ (eq:SI (match_dup 2)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 3)))]
+ "TARGET_HTM"
+{
+ operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tbegin_internal"
+ [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
+ UNSPECV_HTM_TBEGIN))]
+ "TARGET_HTM"
+ "tbegin. %0"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tcheck"
+ [(set (match_dup 2)
+ (unspec_volatile:CC [(match_operand 1 "u3bit_cint_operand" "n")]
+ UNSPECV_HTM_TCHECK))
+ (set (match_dup 3)
+ (eq:SI (match_dup 2)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 3)))]
+ "TARGET_HTM"
+{
+ operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tcheck_internal"
+ [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "u3bit_cint_operand" "n")]
+ UNSPECV_HTM_TCHECK))]
+ "TARGET_HTM"
+ "tcheck. %0"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tend"
+ [(set (match_dup 2)
+ (unspec_volatile:CC [(match_operand 1 "const_0_to_1_operand" "n")]
+ UNSPECV_HTM_TEND))
+ (set (match_dup 3)
+ (eq:SI (match_dup 2)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 3)))]
+ "TARGET_HTM"
+{
+ operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tend_internal"
+ [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
+ UNSPECV_HTM_TEND))]
+ "TARGET_HTM"
+ "tend. %0"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "trechkpt"
+ [(set (match_dup 1)
+ (unspec_volatile:CC [(const_int 0)]
+ UNSPECV_HTM_TRECHKPT))
+ (set (match_dup 2)
+ (eq:SI (match_dup 1)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 2)))]
+ "TARGET_HTM"
+{
+ operands[1] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[2] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*trechkpt_internal"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(const_int 0)]
+ UNSPECV_HTM_TRECHKPT))]
+ "TARGET_HTM"
+ "trechkpt."
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "treclaim"
+ [(set (match_dup 2)
+ (unspec_volatile:CC [(match_operand:SI 1 "gpc_reg_operand" "r")]
+ UNSPECV_HTM_TRECLAIM))
+ (set (match_dup 3)
+ (eq:SI (match_dup 2)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 3)))]
+ "TARGET_HTM"
+{
+ operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*treclaim_internal"
+ [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")]
+ UNSPECV_HTM_TRECLAIM))]
+ "TARGET_HTM"
+ "treclaim. %0"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_expand "tsr"
+ [(set (match_dup 2)
+ (unspec_volatile:CC [(match_operand 1 "const_0_to_1_operand" "n")]
+ UNSPECV_HTM_TSR))
+ (set (match_dup 3)
+ (eq:SI (match_dup 2)
+ (const_int 0)))
+ (set (match_operand:SI 0 "int_reg_operand" "")
+ (minus:SI (const_int 1) (match_dup 3)))]
+ "TARGET_HTM"
+{
+ operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+ operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tsr_internal"
+ [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
+ UNSPECV_HTM_TSR))]
+ "TARGET_HTM"
+ "tsr. %0"
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_insn "htm_mfspr_<mode>"
+ [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+ (unspec_volatile:P [(match_operand 1 "u10bit_cint_operand" "n")
+ (match_operand:P 2 "htm_spr_reg_operand" "")]
+ UNSPECV_HTM_MFSPR))]
+ "TARGET_HTM"
+ "mfspr %0,%1";
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
+
+(define_insn "htm_mtspr_<mode>"
+ [(set (match_operand:P 2 "htm_spr_reg_operand" "")
+ (unspec_volatile:P [(match_operand:P 0 "gpc_reg_operand" "r")
+ (match_operand 1 "u10bit_cint_operand" "n")]
+ UNSPECV_HTM_MTSPR))]
+ "TARGET_HTM"
+ "mtspr %1,%0";
+ [(set_attr "type" "htm")
+ (set_attr "length" "4")])
diff --git a/gcc/config/rs6000/htmintrin.h b/gcc/config/rs6000/htmintrin.h
new file mode 100644
index 00000000000..10f3e2e40a2
--- /dev/null
+++ b/gcc/config/rs6000/htmintrin.h
@@ -0,0 +1,131 @@
+/* Hardware Transactional Memory (HTM) intrinsics.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Peter Bergner <bergner@vnet.ibm.com>.
+
+ This file is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option)
+ any later version.
+
+ This file is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef __HTM__
+# error "HTM instruction set not enabled"
+#endif /* __HTM__ */
+
+#ifndef _HTMINTRIN_H
+#define _HTMINTRIN_H
+
+#include <stdint.h>
+
+typedef uint64_t texasr_t;
+typedef uint32_t texasru_t;
+typedef uint32_t texasrl_t;
+typedef uintptr_t tfiar_t;
+typedef uintptr_t tfhar_t;
+
+#define _HTM_STATE(CR0) ((CR0 >> 1) & 0x3)
+#define _HTM_NONTRANSACTIONAL 0x0
+#define _HTM_SUSPENDED 0x1
+#define _HTM_TRANSACTIONAL 0x2
+
+/* The following macros use the IBM bit numbering for BITNUM
+ as used in the ISA documentation. */
+
+#define _TEXASR_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \
+ (((TEXASR) >> (63-(BITNUM))) & ((1<<(SIZE))-1))
+#define _TEXASRU_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \
+ (((TEXASR) >> (31-(BITNUM))) & ((1<<(SIZE))-1))
+
+#define _TEXASR_FAILURE_CODE(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 7, 8)
+#define _TEXASRU_FAILURE_CODE(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 8)
+
+#define _TEXASR_FAILURE_PERSISTENT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 7, 1)
+#define _TEXASRU_FAILURE_PERSISTENT(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 1)
+
+#define _TEXASR_DISALLOWED(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 8, 1)
+#define _TEXASRU_DISALLOWED(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 8, 1)
+
+#define _TEXASR_NESTING_OVERFLOW(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 9, 1)
+#define _TEXASRU_NESTING_OVERFLOW(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 9, 1)
+
+#define _TEXASR_FOOTPRINT_OVERFLOW(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 10, 1)
+#define _TEXASRU_FOOTPRINT_OVERFLOW(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 10, 1)
+
+#define _TEXASR_SELF_INDUCED_CONFLICT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 11, 1)
+#define _TEXASRU_SELF_INDUCED_CONFLICT(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 11, 1)
+
+#define _TEXASR_NON_TRANSACTIONAL_CONFLICT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 12, 1)
+#define _TEXASRU_NON_TRANSACTIONAL_CONFLICT(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 12, 1)
+
+#define _TEXASR_TRANSACTION_CONFLICT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 13, 1)
+#define _TEXASRU_TRANSACTION_CONFLICT(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 13, 1)
+
+#define _TEXASR_TRANSLATION_INVALIDATION_CONFLICT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 14, 1)
+#define _TEXASRU_TRANSLATION_INVALIDATION_CONFLICT(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 14, 1)
+
+#define _TEXASR_IMPLEMENTAION_SPECIFIC(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 15, 1)
+#define _TEXASRU_IMPLEMENTAION_SPECIFIC(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 15, 1)
+
+#define _TEXASR_INSRUCTION_FETCH_CONFLICT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 16, 1)
+#define _TEXASRU_INSRUCTION_FETCH_CONFLICT(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 16, 1)
+
+#define _TEXASR_ABORT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 31, 1)
+#define _TEXASRU_ABORT(TEXASRU) \
+ _TEXASRU_EXTRACT_BITS(TEXASRU, 31, 1)
+
+
+#define _TEXASR_SUSPENDED(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 32, 1)
+
+#define _TEXASR_PRIVILEGE(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 35, 2)
+
+#define _TEXASR_FAILURE_SUMMARY(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 36, 1)
+
+#define _TEXASR_TFIAR_EXACT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 37, 1)
+
+#define _TEXASR_ROT(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 38, 1)
+
+#define _TEXASR_TRANSACTION_LEVEL(TEXASR) \
+ _TEXASR_EXTRACT_BITS(TEXASR, 63, 12)
+
+#endif /* _HTMINTRIN_H */
diff --git a/gcc/config/rs6000/htmxlintrin.h b/gcc/config/rs6000/htmxlintrin.h
new file mode 100644
index 00000000000..c2077d2a370
--- /dev/null
+++ b/gcc/config/rs6000/htmxlintrin.h
@@ -0,0 +1,208 @@
+/* XL compiler Hardware Transactional Memory (HTM) execution intrinsics.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Peter Bergner <bergner@vnet.ibm.com>.
+
+ This file is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option)
+ any later version.
+
+ This file is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef __HTM__
+# error "HTM instruction set not enabled"
+#endif /* __HTM__ */
+
+#ifndef _HTMXLINTRIN_H
+#define _HTMXLINTRIN_H
+
+#include <stdint.h>
+#include <htmintrin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _TEXASR_PTR(TM_BUF) \
+ ((texasr_t *)((TM_BUF)+0))
+#define _TEXASRU_PTR(TM_BUF) \
+ ((texasru_t *)((TM_BUF)+0))
+#define _TEXASRL_PTR(TM_BUF) \
+ ((texasrl_t *)((TM_BUF)+4))
+#define _TFIAR_PTR(TM_BUF) \
+ ((tfiar_t *)((TM_BUF)+8))
+
+typedef char TM_buff_type[16];
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_simple_begin (void)
+{
+ if (__builtin_expect (__builtin_tbegin (0), 1))
+ return 1;
+ return 0;
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_begin (void* const TM_buff)
+{
+ *_TEXASRL_PTR (TM_buff) = 0;
+ if (__builtin_expect (__builtin_tbegin (0), 1))
+ return 1;
+#ifdef __powerpc64__
+ *_TEXASR_PTR (TM_buff) = __builtin_get_texasr ();
+#else
+ *_TEXASRU_PTR (TM_buff) = __builtin_get_texasru ();
+ *_TEXASRL_PTR (TM_buff) = __builtin_get_texasr ();
+#endif
+ *_TFIAR_PTR (TM_buff) = __builtin_get_tfiar ();
+ return 0;
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_end (void)
+{
+ if (__builtin_expect (__builtin_tend (0), 1))
+ return 1;
+ return 0;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_abort (void)
+{
+ __builtin_tabort (0);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_named_abort (unsigned char const code)
+{
+ __builtin_tabort (code);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_resume (void)
+{
+ __builtin_tresume ();
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_suspend (void)
+{
+ __builtin_tsuspend ();
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_user_abort (void* const TM_buff)
+{
+ texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+ return _TEXASRU_ABORT (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_named_user_abort (void* const TM_buff, unsigned char *code)
+{
+ texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+
+ *code = _TEXASRU_FAILURE_CODE (texasru);
+ return _TEXASRU_ABORT (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_illegal (void* const TM_buff)
+{
+ texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+ return _TEXASRU_DISALLOWED (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_footprint_exceeded (void* const TM_buff)
+{
+ texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+ return _TEXASRU_FOOTPRINT_OVERFLOW (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_nesting_depth (void* const TM_buff)
+{
+ texasrl_t texasrl;
+
+ if (_HTM_STATE (__builtin_ttest ()) == _HTM_NONTRANSACTIONAL)
+ {
+ texasrl = *_TEXASRL_PTR (TM_buff);
+ if (!_TEXASR_FAILURE_SUMMARY (texasrl))
+ texasrl = 0;
+ }
+ else
+ texasrl = (texasrl_t) __builtin_get_texasr ();
+
+ return _TEXASR_TRANSACTION_LEVEL (texasrl);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_nested_too_deep(void* const TM_buff)
+{
+ texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+ return _TEXASRU_NESTING_OVERFLOW (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_conflict(void* const TM_buff)
+{
+ texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+ /* Return TEXASR bits 11 (Self-Induced Conflict) through
+ 14 (Translation Invalidation Conflict). */
+ return (_TEXASRU_EXTRACT_BITS (texasru, 14, 4)) ? 1 : 0;
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_failure_persistent(void* const TM_buff)
+{
+ texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+ return _TEXASRU_FAILURE_PERSISTENT (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_failure_address(void* const TM_buff)
+{
+ return *_TFIAR_PTR (TM_buff);
+}
+
+extern __inline long long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_failure_code(void* const TM_buff)
+{
+ return *_TEXASR_PTR (TM_buff);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HTMXLINTRIN_H */
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index f47967a48aa..18912f15a4a 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -124,6 +124,11 @@
(and (match_code "const_int")
(match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")))
+;; Return 1 if op is a unsigned 3-bit constant integer.
+(define_predicate "u3bit_cint_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7")))
+
;; Return 1 if op is a unsigned 5-bit constant integer.
(define_predicate "u5bit_cint_operand"
(and (match_code "const_int")
@@ -135,6 +140,11 @@
(and (match_code "const_int")
(match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127")))
+;; Return 1 if op is a unsigned 10-bit constant integer.
+(define_predicate "u10bit_cint_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 1023")))
+
;; Return 1 if op is a constant integer that can fit in a D field.
(define_predicate "short_cint_operand"
(and (match_code "const_int")
@@ -226,6 +236,33 @@
return (REGNO (op) != FIRST_GPR_REGNO);
})
+;; Return 1 if op is a HTM specific SPR register.
+(define_predicate "htm_spr_reg_operand"
+ (match_operand 0 "register_operand")
+{
+ if (!TARGET_HTM)
+ return 0;
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ switch (REGNO (op))
+ {
+ case TFHAR_REGNO:
+ case TFIAR_REGNO:
+ case TEXASR_REGNO:
+ return 1;
+ default:
+ break;
+ }
+
+ /* Unknown SPR. */
+ return 0;
+})
+
;; Return 1 if op is a general purpose register that is an even register
;; which suitable for a load/store quad operation
(define_predicate "quad_int_reg_operand"
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 1a5a709751d..672604406d5 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -30,6 +30,7 @@
RS6000_BUILTIN_A -- ABS builtins
RS6000_BUILTIN_D -- DST builtins
RS6000_BUILTIN_E -- SPE EVSEL builtins.
+ RS6000_BUILTIN_H -- HTM builtins
RS6000_BUILTIN_P -- Altivec, VSX, ISA 2.07 vector predicate builtins
RS6000_BUILTIN_Q -- Paired floating point VSX predicate builtins
RS6000_BUILTIN_S -- SPE predicate builtins
@@ -66,6 +67,10 @@
#error "RS6000_BUILTIN_E is not defined."
#endif
+#ifndef RS6000_BUILTIN_H
+ #error "RS6000_BUILTIN_H is not defined."
+#endif
+
#ifndef RS6000_BUILTIN_P
#error "RS6000_BUILTIN_P is not defined."
#endif
@@ -403,6 +408,56 @@
| RS6000_BTC_TERNARY), \
CODE_FOR_nothing) /* ICODE */
+/* HTM convenience macros. */
+#define BU_HTM_0(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HTM, /* MASK */ \
+ RS6000_BTC_ ## ATTR, /* ATTR */ \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_HTM_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HTM, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_HTM_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HTM, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_HTM_3(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HTM, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_TERNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_HTM_SPR0(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HTM, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_SPR), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_HTM_SPR1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HTM, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY \
+ | RS6000_BTC_SPR \
+ | RS6000_BTC_VOID), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
/* SPE convenience macros. */
#define BU_SPE_1(ENUM, NAME, ATTR, ICODE) \
RS6000_BUILTIN_1 (SPE_BUILTIN_ ## ENUM, /* ENUM */ \
@@ -1367,6 +1422,33 @@ BU_CRYPTO_OVERLOAD_3 (VPERMXOR, "vpermxor")
BU_CRYPTO_OVERLOAD_3 (VSHASIGMA, "vshasigma")
+/* HTM functions. */
+BU_HTM_1 (TABORT, "tabort", MISC, tabort)
+BU_HTM_3 (TABORTDC, "tabortdc", MISC, tabortdc)
+BU_HTM_3 (TABORTDCI, "tabortdci", MISC, tabortdci)
+BU_HTM_3 (TABORTWC, "tabortwc", MISC, tabortwc)
+BU_HTM_3 (TABORTWCI, "tabortwci", MISC, tabortwci)
+BU_HTM_1 (TBEGIN, "tbegin", MISC, tbegin)
+BU_HTM_1 (TCHECK, "tcheck", MISC, tcheck)
+BU_HTM_1 (TEND, "tend", MISC, tend)
+BU_HTM_0 (TENDALL, "tendall", MISC, tend)
+BU_HTM_0 (TRECHKPT, "trechkpt", MISC, trechkpt)
+BU_HTM_1 (TRECLAIM, "treclaim", MISC, treclaim)
+BU_HTM_0 (TRESUME, "tresume", MISC, tsr)
+BU_HTM_0 (TSUSPEND, "tsuspend", MISC, tsr)
+BU_HTM_1 (TSR, "tsr", MISC, tsr)
+BU_HTM_0 (TTEST, "ttest", MISC, ttest)
+
+BU_HTM_SPR0 (GET_TFHAR, "get_tfhar", MISC, nothing)
+BU_HTM_SPR1 (SET_TFHAR, "set_tfhar", MISC, nothing)
+BU_HTM_SPR0 (GET_TFIAR, "get_tfiar", MISC, nothing)
+BU_HTM_SPR1 (SET_TFIAR, "set_tfiar", MISC, nothing)
+BU_HTM_SPR0 (GET_TEXASR, "get_texasr", MISC, nothing)
+BU_HTM_SPR1 (SET_TEXASR, "set_texasr", MISC, nothing)
+BU_HTM_SPR0 (GET_TEXASRU, "get_texasru", MISC, nothing)
+BU_HTM_SPR1 (SET_TEXASRU, "set_texasru", MISC, nothing)
+
+
/* 3 argument paired floating point builtins. */
BU_PAIRED_3 (MSUB, "msub", FP, fmsv2sf4)
BU_PAIRED_3 (MADD, "madd", FP, fmav2sf4)
@@ -1665,10 +1747,10 @@ BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf", RS6000_BTM_FRSQRTES,
RS6000_BTC_FP)
BU_SPECIAL_X (RS6000_BUILTIN_GET_TB, "__builtin_ppc_get_timebase",
- RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+ RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb",
- RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+ RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
/* Darwin CfString builtin. */
BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 593b772ebd1..d58e6865193 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -333,6 +333,8 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
}
if ((flags & OPTION_MASK_VSX) != 0)
rs6000_define_or_undefine_macro (define_p, "__VSX__");
+ if ((flags & OPTION_MASK_HTM) != 0)
+ rs6000_define_or_undefine_macro (define_p, "__HTM__");
if ((flags & OPTION_MASK_P8_VECTOR) != 0)
rs6000_define_or_undefine_macro (define_p, "__POWER8_VECTOR__");
if ((flags & OPTION_MASK_CRYPTO) != 0)
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index 08346b61d17..c177512ddfd 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -51,6 +51,7 @@
| OPTION_MASK_P8_VECTOR \
| OPTION_MASK_CRYPTO \
| OPTION_MASK_DIRECT_MOVE \
+ | OPTION_MASK_HTM \
| OPTION_MASK_QUAD_MEMORY)
#define POWERPC_7400_MASK (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC)
@@ -74,6 +75,7 @@
| OPTION_MASK_DIRECT_MOVE \
| OPTION_MASK_DLMZB \
| OPTION_MASK_FPRND \
+ | OPTION_MASK_HTM \
| OPTION_MASK_ISEL \
| OPTION_MASK_MFCRF \
| OPTION_MASK_MFPGPR \
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index aabef7f703c..3d86bd13381 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -910,6 +910,7 @@ struct processor_costs ppca2_cost = {
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -933,6 +934,9 @@ struct processor_costs ppca2_cost = {
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) \
{ NAME, ICODE, MASK, ATTR },
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
{ NAME, ICODE, MASK, ATTR },
@@ -963,6 +967,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -1003,6 +1008,7 @@ static void rs6000_common_init_builtins (void);
static void paired_init_builtins (void);
static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
static void spe_init_builtins (void);
+static void htm_init_builtins (void);
static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
@@ -1130,7 +1136,9 @@ char rs6000_reg_names[][8] =
/* SPE registers. */
"spe_acc", "spefscr",
/* Soft frame pointer. */
- "sfp"
+ "sfp",
+ /* HTM SPR registers. */
+ "tfhar", "tfiar", "texasr"
};
#ifdef TARGET_REGNAMES
@@ -1156,7 +1164,9 @@ static const char alt_reg_names[][8] =
/* SPE registers. */
"spe_acc", "spefscr",
/* Soft frame pointer. */
- "sfp"
+ "sfp",
+ /* HTM SPR registers. */
+ "tfhar", "tfiar", "texasr"
};
#endif
@@ -2190,6 +2200,9 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
+ rs6000_regno_regclass[TFHAR_REGNO] = SPR_REGS;
+ rs6000_regno_regclass[TFIAR_REGNO] = SPR_REGS;
+ rs6000_regno_regclass[TEXASR_REGNO] = SPR_REGS;
rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
@@ -2711,7 +2724,8 @@ rs6000_builtin_mask_calculate (void)
| ((TARGET_POPCNTD) ? RS6000_BTM_POPCNTD : 0)
| ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL : 0)
| ((TARGET_P8_VECTOR) ? RS6000_BTM_P8_VECTOR : 0)
- | ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0));
+ | ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0)
+ | ((TARGET_HTM) ? RS6000_BTM_HTM : 0));
}
/* Override command line options. Mostly we process the processor type and
@@ -10144,6 +10158,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10157,6 +10172,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10175,6 +10191,7 @@ static const struct builtin_description bdesc_3arg[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10188,6 +10205,7 @@ static const struct builtin_description bdesc_3arg[] =
{ MASK, ICODE, NAME, ENUM },
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10206,6 +10224,7 @@ static const struct builtin_description bdesc_dst[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10219,6 +10238,7 @@ static const struct builtin_description bdesc_dst[] =
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10235,6 +10255,7 @@ static const struct builtin_description bdesc_2arg[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10246,6 +10267,7 @@ static const struct builtin_description bdesc_2arg[] =
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
@@ -10267,6 +10289,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10278,6 +10301,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) \
@@ -10297,6 +10321,7 @@ static const struct builtin_description bdesc_spe_predicates[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10310,6 +10335,7 @@ static const struct builtin_description bdesc_spe_predicates[] =
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10327,6 +10353,7 @@ static const struct builtin_description bdesc_spe_evsel[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10338,6 +10365,7 @@ static const struct builtin_description bdesc_spe_evsel[] =
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
@@ -10358,6 +10386,7 @@ static const struct builtin_description bdesc_paired_preds[] =
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10371,6 +10400,7 @@ static const struct builtin_description bdesc_paired_preds[] =
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10388,8 +10418,9 @@ static const struct builtin_description bdesc_abs[] =
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_E
#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -10403,6 +10434,7 @@ static const struct builtin_description bdesc_abs[] =
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10413,17 +10445,49 @@ static const struct builtin_description bdesc_1arg[] =
#include "rs6000-builtin.def"
};
+/* HTM builtins. */
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_htm[] =
+{
+#include "rs6000-builtin.def"
+};
+
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_Q
+#undef RS6000_BUILTIN_S
+
/* Return true if a builtin function is overloaded. */
bool
rs6000_overloaded_builtin_p (enum rs6000_builtins fncode)
@@ -10893,6 +10957,197 @@ altivec_expand_stv_builtin (enum insn_code icode, tree exp)
return NULL_RTX;
}
+/* Return the appropriate SPR number associated with the given builtin. */
+static inline HOST_WIDE_INT
+htm_spr_num (enum rs6000_builtins code)
+{
+ if (code == HTM_BUILTIN_GET_TFHAR
+ || code == HTM_BUILTIN_SET_TFHAR)
+ return TFHAR_SPR;
+ else if (code == HTM_BUILTIN_GET_TFIAR
+ || code == HTM_BUILTIN_SET_TFIAR)
+ return TFIAR_SPR;
+ else if (code == HTM_BUILTIN_GET_TEXASR
+ || code == HTM_BUILTIN_SET_TEXASR)
+ return TEXASR_SPR;
+ gcc_assert (code == HTM_BUILTIN_GET_TEXASRU
+ || code == HTM_BUILTIN_SET_TEXASRU);
+ return TEXASRU_SPR;
+}
+
+/* Return the appropriate SPR regno associated with the given builtin. */
+static inline HOST_WIDE_INT
+htm_spr_regno (enum rs6000_builtins code)
+{
+ if (code == HTM_BUILTIN_GET_TFHAR
+ || code == HTM_BUILTIN_SET_TFHAR)
+ return TFHAR_REGNO;
+ else if (code == HTM_BUILTIN_GET_TFIAR
+ || code == HTM_BUILTIN_SET_TFIAR)
+ return TFIAR_REGNO;
+ gcc_assert (code == HTM_BUILTIN_GET_TEXASR
+ || code == HTM_BUILTIN_SET_TEXASR
+ || code == HTM_BUILTIN_GET_TEXASRU
+ || code == HTM_BUILTIN_SET_TEXASRU);
+ return TEXASR_REGNO;
+}
+
+/* Return the correct ICODE value depending on whether we are
+ setting or reading the HTM SPRs. */
+static inline enum insn_code
+rs6000_htm_spr_icode (bool nonvoid)
+{
+ if (nonvoid)
+ return (TARGET_64BIT) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si;
+ else
+ return (TARGET_64BIT) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si;
+}
+
+/* Expand the HTM builtin in EXP and store the result in TARGET.
+ Store true in *EXPANDEDP if we found a builtin to expand. */
+static rtx
+htm_expand_builtin (tree exp, rtx target, bool * expandedp)
+{
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ const struct builtin_description *d;
+ size_t i;
+
+ *expandedp = false;
+
+ /* Expand the HTM builtins. */
+ d = bdesc_htm;
+ for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
+ if (d->code == fcode)
+ {
+ rtx op[MAX_HTM_OPERANDS], pat;
+ int nopnds = 0;
+ tree arg;
+ call_expr_arg_iterator iter;
+ unsigned attr = rs6000_builtin_info[fcode].attr;
+ enum insn_code icode = d->icode;
+
+ if (attr & RS6000_BTC_SPR)
+ icode = rs6000_htm_spr_icode (nonvoid);
+
+ if (nonvoid)
+ {
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ if (!target
+ || GET_MODE (target) != tmode
+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ op[nopnds++] = target;
+ }
+
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+ {
+ const struct insn_operand_data *insn_op;
+
+ if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS)
+ return NULL_RTX;
+
+ insn_op = &insn_data[icode].operand[nopnds];
+
+ op[nopnds] = expand_normal (arg);
+
+ if (!(*insn_op->predicate) (op[nopnds], insn_op->mode))
+ {
+ if (!strcmp (insn_op->constraint, "n"))
+ {
+ int arg_num = (nonvoid) ? nopnds : nopnds + 1;
+ if (!CONST_INT_P (op[nopnds]))
+ error ("argument %d must be an unsigned literal", arg_num);
+ else
+ error ("argument %d is an unsigned literal that is "
+ "out of range", arg_num);
+ return const0_rtx;
+ }
+ op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]);
+ }
+
+ nopnds++;
+ }
+
+ /* Handle the builtins for extended mnemonics. These accept
+ no arguments, but map to builtins that take arguments. */
+ switch (fcode)
+ {
+ case HTM_BUILTIN_TENDALL: /* Alias for: tend. 1 */
+ case HTM_BUILTIN_TRESUME: /* Alias for: tsr. 1 */
+ op[nopnds++] = GEN_INT (1);
+#ifdef ENABLE_CHECKING
+ attr |= RS6000_BTC_UNARY;
+#endif
+ break;
+ case HTM_BUILTIN_TSUSPEND: /* Alias for: tsr. 0 */
+ op[nopnds++] = GEN_INT (0);
+#ifdef ENABLE_CHECKING
+ attr |= RS6000_BTC_UNARY;
+#endif
+ break;
+ default:
+ break;
+ }
+
+ /* If this builtin accesses SPRs, then pass in the appropriate
+ SPR number and SPR regno as the last two operands. */
+ if (attr & RS6000_BTC_SPR)
+ {
+ op[nopnds++] = gen_rtx_CONST_INT (Pmode, htm_spr_num (fcode));
+ op[nopnds++] = gen_rtx_REG (Pmode, htm_spr_regno (fcode));
+ }
+
+#ifdef ENABLE_CHECKING
+ int expected_nopnds = 0;
+ if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_UNARY)
+ expected_nopnds = 1;
+ else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_BINARY)
+ expected_nopnds = 2;
+ else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_TERNARY)
+ expected_nopnds = 3;
+ if (!(attr & RS6000_BTC_VOID))
+ expected_nopnds += 1;
+ if (attr & RS6000_BTC_SPR)
+ expected_nopnds += 2;
+
+ gcc_assert (nopnds == expected_nopnds && nopnds <= MAX_HTM_OPERANDS);
+#endif
+
+ switch (nopnds)
+ {
+ case 0:
+ pat = GEN_FCN (icode) (NULL_RTX);
+ break;
+ case 1:
+ pat = GEN_FCN (icode) (op[0]);
+ break;
+ case 2:
+ pat = GEN_FCN (icode) (op[0], op[1]);
+ break;
+ case 3:
+ pat = GEN_FCN (icode) (op[0], op[1], op[2]);
+ break;
+ case 4:
+ pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (!pat)
+ return NULL_RTX;
+ emit_insn (pat);
+
+ *expandedp = true;
+ if (nonvoid)
+ return target;
+ return const0_rtx;
+ }
+
+ return NULL_RTX;
+}
+
static rtx
rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
{
@@ -11974,6 +12229,8 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
error ("Builtin function %s is only valid for the cell processor", name);
else if ((fnmask & RS6000_BTM_VSX) != 0)
error ("Builtin function %s requires the -mvsx option", name);
+ else if ((fnmask & RS6000_BTM_HTM) != 0)
+ error ("Builtin function %s requires the -mhtm option", name);
else if ((fnmask & RS6000_BTM_ALTIVEC) != 0)
error ("Builtin function %s requires the -maltivec option", name);
else if ((fnmask & RS6000_BTM_PAIRED) != 0)
@@ -12153,6 +12410,13 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
if (success)
return ret;
}
+ if (TARGET_HTM)
+ {
+ ret = htm_expand_builtin (exp, target, &success);
+
+ if (success)
+ return ret;
+ }
gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
@@ -12335,6 +12599,9 @@ rs6000_init_builtins (void)
spe_init_builtins ();
if (TARGET_EXTRA_BUILTINS)
altivec_init_builtins ();
+ if (TARGET_HTM)
+ htm_init_builtins ();
+
if (TARGET_EXTRA_BUILTINS || TARGET_SPE || TARGET_PAIRED_FLOAT)
rs6000_common_init_builtins ();
@@ -13074,6 +13341,79 @@ altivec_init_builtins (void)
def_builtin ("__builtin_vec_ext_v2di", ftype, VSX_BUILTIN_VEC_EXT_V2DI);
}
+static void
+htm_init_builtins (void)
+{
+ HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
+ const struct builtin_description *d;
+ size_t i;
+
+ d = bdesc_htm;
+ for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
+ {
+ tree op[MAX_HTM_OPERANDS], type;
+ HOST_WIDE_INT mask = d->mask;
+ unsigned attr = rs6000_builtin_info[d->code].attr;
+ bool void_func = (attr & RS6000_BTC_VOID);
+ int attr_args = (attr & RS6000_BTC_TYPE_MASK);
+ int nopnds = 0;
+ tree argtype = (attr & RS6000_BTC_SPR) ? long_unsigned_type_node
+ : unsigned_type_node;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "htm_builtin, skip binary %s\n", d->name);
+ continue;
+ }
+
+ if (d->name == 0)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "htm_builtin, bdesc_htm[%ld] no name\n",
+ (long unsigned) i);
+ continue;
+ }
+
+ op[nopnds++] = (void_func) ? void_type_node : argtype;
+
+ if (attr_args == RS6000_BTC_UNARY)
+ op[nopnds++] = argtype;
+ else if (attr_args == RS6000_BTC_BINARY)
+ {
+ op[nopnds++] = argtype;
+ op[nopnds++] = argtype;
+ }
+ else if (attr_args == RS6000_BTC_TERNARY)
+ {
+ op[nopnds++] = argtype;
+ op[nopnds++] = argtype;
+ op[nopnds++] = argtype;
+ }
+
+ switch (nopnds)
+ {
+ case 1:
+ type = build_function_type_list (op[0], NULL_TREE);
+ break;
+ case 2:
+ type = build_function_type_list (op[0], op[1], NULL_TREE);
+ break;
+ case 3:
+ type = build_function_type_list (op[0], op[1], op[2], NULL_TREE);
+ break;
+ case 4:
+ type = build_function_type_list (op[0], op[1], op[2], op[3],
+ NULL_TREE);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ def_builtin (d->name, type, d->code);
+ }
+}
+
/* Hash function for builtin functions with up to 3 arguments and a return
type. */
static unsigned
@@ -28777,6 +29117,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
{ "dlmzb", OPTION_MASK_DLMZB, false, true },
{ "fprnd", OPTION_MASK_FPRND, false, true },
{ "hard-dfp", OPTION_MASK_DFP, false, true },
+ { "htm", OPTION_MASK_HTM, false, true },
{ "isel", OPTION_MASK_ISEL, false, true },
{ "mfcrf", OPTION_MASK_MFCRF, false, true },
{ "mfpgpr", OPTION_MASK_MFPGPR, false, true },
@@ -28836,6 +29177,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
{ "cell", RS6000_BTM_CELL, false, false },
{ "power8-vector", RS6000_BTM_P8_VECTOR, false, false },
{ "crypto", RS6000_BTM_CRYPTO, false, false },
+ { "htm", RS6000_BTM_HTM, false, false },
};
/* Option variables that we want to support inside attribute((target)) and
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 98a44aa32e1..8e96fbf356b 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -164,7 +164,7 @@
%{mcpu=e6500: -me6500} \
%{maltivec: -maltivec} \
%{mvsx: -mvsx %{!maltivec: -maltivec} %{!mcpu*: %(asm_cpu_power7)}} \
-%{mpower8-vector|mcrypto|mdirect-move: %{!mcpu*: %(asm_cpu_power8)}} \
+%{mpower8-vector|mcrypto|mdirect-move|mhtm: %{!mcpu*: %(asm_cpu_power8)}} \
-many"
#define CPP_DEFAULT_SPEC ""
@@ -285,9 +285,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#ifndef HAVE_AS_POWER8
#undef TARGET_DIRECT_MOVE
#undef TARGET_CRYPTO
+#undef TARGET_HTM
#undef TARGET_P8_VECTOR
#define TARGET_DIRECT_MOVE 0
#define TARGET_CRYPTO 0
+#define TARGET_HTM 0
#define TARGET_P8_VECTOR 0
#endif
@@ -543,6 +545,7 @@ extern int rs6000_vector_align[];
#define MASK_FPRND OPTION_MASK_FPRND
#define MASK_P8_FUSION OPTION_MASK_P8_FUSION
#define MASK_HARD_FLOAT OPTION_MASK_HARD_FLOAT
+#define MASK_HTM OPTION_MASK_HTM
#define MASK_ISEL OPTION_MASK_ISEL
#define MASK_MFCRF OPTION_MASK_MFCRF
#define MASK_MFPGPR OPTION_MASK_MFPGPR
@@ -889,15 +892,17 @@ enum data_align { align_abi, align_opt, align_both };
in inline functions.
Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame
- pointer, which is eventually eliminated in favor of SP or FP. */
+ pointer, which is eventually eliminated in favor of SP or FP.
-#define FIRST_PSEUDO_REGISTER 114
+ The 3 HTM registers aren't also included in DWARF_FRAME_REGISTERS. */
+
+#define FIRST_PSEUDO_REGISTER 117
/* This must be included for pre gcc 3.0 glibc compatibility. */
#define PRE_GCC3_DWARF_FRAME_REGISTERS 77
/* Add 32 dwarf columns for synthetic SPE registers. */
-#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 1) + 32)
+#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 4) + 32)
/* The SPE has an additional 32 synthetic registers, with DWARF debug
info numbering for these registers starting at 1200. While eh_frame
@@ -913,7 +918,7 @@ enum data_align { align_abi, align_opt, align_both };
We must map them here to avoid huge unwinder tables mostly consisting
of unused space. */
#define DWARF_REG_TO_UNWIND_COLUMN(r) \
- ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER - 1) : (r))
+ ((r) > 1200 ? ((r) - 1200 + (DWARF_FRAME_REGISTERS - 32)) : (r))
/* Use standard DWARF numbering for DWARF debugging information. */
#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
@@ -953,7 +958,7 @@ enum data_align { align_abi, align_opt, align_both };
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1 \
- , 1, 1, 1 \
+ , 1, 1, 1, 1, 1, 1 \
}
/* 1 for registers not available across function calls.
@@ -973,7 +978,7 @@ enum data_align { align_abi, align_opt, align_both };
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1 \
- , 1, 1, 1 \
+ , 1, 1, 1, 1, 1, 1 \
}
/* Like `CALL_USED_REGISTERS' except this macro doesn't require that
@@ -992,7 +997,7 @@ enum data_align { align_abi, align_opt, align_both };
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0 \
- , 0, 0, 0 \
+ , 0, 0, 0, 0, 0, 0 \
}
#define TOTAL_ALTIVEC_REGS (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1)
@@ -1031,6 +1036,9 @@ enum data_align { align_abi, align_opt, align_both };
vrsave, vscr (fixed)
spe_acc, spefscr (fixed)
sfp (fixed)
+ tfhar (fixed)
+ tfiar (fixed)
+ texasr (fixed)
*/
#if FIXED_R2 == 1
@@ -1072,7 +1080,7 @@ enum data_align { align_abi, align_opt, align_both };
96, 95, 94, 93, 92, 91, \
108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, \
109, 110, \
- 111, 112, 113 \
+ 111, 112, 113, 114, 115, 116 \
}
/* True if register is floating-point. */
@@ -1299,6 +1307,7 @@ enum reg_class
VSCR_REGS,
SPE_ACC_REGS,
SPEFSCR_REGS,
+ SPR_REGS,
NON_SPECIAL_REGS,
LINK_REGS,
CTR_REGS,
@@ -1329,6 +1338,7 @@ enum reg_class
"VSCR_REGS", \
"SPE_ACC_REGS", \
"SPEFSCR_REGS", \
+ "SPR_REGS", \
"NON_SPECIAL_REGS", \
"LINK_REGS", \
"CTR_REGS", \
@@ -1358,6 +1368,7 @@ enum reg_class
{ 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00040000 }, /* SPR_REGS */ \
{ 0xffffffff, 0xffffffff, 0x00000008, 0x00020000 }, /* NON_SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \
{ 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */ \
@@ -1368,7 +1379,7 @@ enum reg_class
{ 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \
{ 0xffffffff, 0x00000000, 0x00000ffe, 0x00020000 }, /* NON_FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* CA_REGS */ \
- { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0003ffff } /* ALL_REGS */ \
+ { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0007ffff } /* ALL_REGS */ \
}
/* The same information, inverted:
@@ -2282,6 +2293,9 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
&rs6000_reg_names[111][0], /* spe_acc */ \
&rs6000_reg_names[112][0], /* spefscr */ \
&rs6000_reg_names[113][0], /* sfp */ \
+ &rs6000_reg_names[114][0], /* tfhar */ \
+ &rs6000_reg_names[115][0], /* tfiar */ \
+ &rs6000_reg_names[116][0], /* texasr */ \
}
/* Table of additional register names to use in user input. */
@@ -2335,7 +2349,9 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"vs48", 93}, {"vs49", 94}, {"vs50", 95}, {"vs51", 96}, \
{"vs52", 97}, {"vs53", 98}, {"vs54", 99}, {"vs55", 100}, \
{"vs56", 101},{"vs57", 102},{"vs58", 103},{"vs59", 104}, \
- {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108} }
+ {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108}, \
+ /* Transactional Memory Facility (HTM) Registers. */ \
+ {"tfhar", 114}, {"tfiar", 115}, {"texasr", 116} }
/* This is how to output an element of a case-vector that is relative. */
@@ -2424,7 +2440,12 @@ extern int frame_pointer_needed;
#define RS6000_BTC_ATTR_MASK 0x00000700 /* Mask of the attributes. */
/* Miscellaneous information. */
-#define RS6000_BTC_OVERLOADED 0x4000000 /* function is overloaded. */
+#define RS6000_BTC_SPR 0x01000000 /* function references SPRs. */
+#define RS6000_BTC_VOID 0x02000000 /* function has no return value. */
+#define RS6000_BTC_OVERLOADED 0x04000000 /* function is overloaded. */
+#define RS6000_BTC_32BIT 0x08000000 /* function references SPRs. */
+#define RS6000_BTC_64BIT 0x10000000 /* function references SPRs. */
+#define RS6000_BTC_MISC_MASK 0x1f000000 /* Mask of the misc info. */
/* Convenience macros to document the instruction type. */
#define RS6000_BTC_MEM RS6000_BTC_MISC /* load/store touches mem. */
@@ -2438,6 +2459,7 @@ extern int frame_pointer_needed;
#define RS6000_BTM_VSX MASK_VSX /* VSX (vector/scalar). */
#define RS6000_BTM_P8_VECTOR MASK_P8_VECTOR /* ISA 2.07 vector. */
#define RS6000_BTM_CRYPTO MASK_CRYPTO /* crypto funcs. */
+#define RS6000_BTM_HTM MASK_HTM /* hardware TM funcs. */
#define RS6000_BTM_SPE MASK_STRING /* E500 */
#define RS6000_BTM_PAIRED MASK_MULHW /* 750CL paired insns. */
#define RS6000_BTM_FRE MASK_POPCNTB /* FRE instruction. */
@@ -2455,6 +2477,7 @@ extern int frame_pointer_needed;
| RS6000_BTM_FRES \
| RS6000_BTM_FRSQRTE \
| RS6000_BTM_FRSQRTES \
+ | RS6000_BTM_HTM \
| RS6000_BTM_POPCNTD \
| RS6000_BTM_CELL)
@@ -2466,6 +2489,7 @@ extern int frame_pointer_needed;
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
@@ -2477,6 +2501,7 @@ extern int frame_pointer_needed;
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
@@ -2495,6 +2520,7 @@ enum rs6000_builtins
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_Q
#undef RS6000_BUILTIN_S
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 731cfae930a..372c8138fc6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -53,6 +53,9 @@
(SPE_ACC_REGNO 111)
(SPEFSCR_REGNO 112)
(FRAME_POINTER_REGNUM 113)
+ (TFHAR_REGNO 114)
+ (TFIAR_REGNO 115)
+ (TEXASR_REGNO 116)
; ABI defined stack offsets for storing the TOC pointer with AIX calls.
(TOC_SAVE_OFFSET_32BIT 20)
@@ -153,7 +156,7 @@
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt,crypto"
+(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt,crypto,htm"
(const_string "integer"))
;; Define floating point instruction sub-types for use with Xfpu.md
@@ -15307,3 +15310,4 @@
(include "dfp.md")
(include "paired.md")
(include "crypto.md")
+(include "htm.md")
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 9a078198130..f36e4758031 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -539,6 +539,10 @@ mdirect-move
Target Report Mask(DIRECT_MOVE) Var(rs6000_isa_flags)
Use ISA 2.07 direct move between GPR & VSX register instructions
+mhtm
+Target Report Mask(HTM) Var(rs6000_isa_flags)
+Use ISA 2.07 transactional memory (HTM) instructions
+
mquad-memory
Target Report Mask(QUAD_MEMORY) Var(rs6000_isa_flags)
Generate the quad word memory instructions (lq/stq/lqarx/stqcx).
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 5889d6d82d4..81372dfb140 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -72,6 +72,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \
$(srcdir)/config/rs6000/vsx.md \
$(srcdir)/config/rs6000/altivec.md \
$(srcdir)/config/rs6000/crypto.md \
+ $(srcdir)/config/rs6000/htm.md \
$(srcdir)/config/rs6000/spe.md \
$(srcdir)/config/rs6000/dfp.md \
$(srcdir)/config/rs6000/paired.md
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 7ce0c30c883..ab4cc8bb269 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9771,11 +9771,8 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
if (icode == 0)
internal_error ("bad builtin fcode");
- if (!TARGET_ZEC12)
- error ("Transactional execution builtins require zEC12 or later\n");
-
- if (!TARGET_HTM && TARGET_ZEC12)
- error ("Transactional execution builtins not enabled (-mtx)\n");
+ if (!TARGET_HTM)
+ error ("Transactional execution builtins not enabled (-mhtm)\n");
/* Set a flag in the machine specific cfun part in order to support
saving/restoring of FPRs. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index d53fed7a6f2..bca18fe36f5 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -81,8 +81,7 @@ enum processor_flags
(TARGET_ZARCH && TARGET_CPU_Z196)
#define TARGET_ZEC12 \
(TARGET_ZARCH && TARGET_CPU_ZEC12)
-#define TARGET_HTM \
- (TARGET_ZARCH && TARGET_CPU_HTM && TARGET_OPT_HTM)
+#define TARGET_HTM (TARGET_OPT_HTM)
#define TARGET_AVOID_CMP_AND_BRANCH (s390_tune == PROCESSOR_2817_Z196)