S/390 Vector base support.

gcc/
	* config/s390/constraints.md (j00, jm1, jxx, jyy, v): New
	constraints.
	* config/s390/predicates.md (const0_operand, constm1_operand)
	(constable_operand): Accept vector operands.
	* config/s390/s390-modes.def: Add supported vector modes.
	* config/s390/s390-protos.h (s390_cannot_change_mode_class)
	(s390_function_arg_vector, s390_contiguous_bitmask_vector_p)
	(s390_bytemask_vector_p, s390_expand_vec_strlen)
	(s390_expand_vec_compare, s390_expand_vcond)
	(s390_expand_vec_init): Add prototypes.
	* config/s390/s390.c (VEC_ARG_NUM_REG): New macro.
	(s390_vector_mode_supported_p): New function.
	(s390_contiguous_bitmask_p): Mask out the irrelevant bits.
	(s390_contiguous_bitmask_vector_p): New function.
	(s390_bytemask_vector_p): New function.
	(s390_split_ok_p): Vector regs don't work either.
	(regclass_map): Add VEC_REGS.
	(s390_legitimate_constant_p): Handle vector constants.
	(s390_cannot_force_const_mem): Handle CONST_VECTOR.
	(legitimate_reload_vector_constant_p): New function.
	(s390_preferred_reload_class): Handle CONST_VECTOR.
	(s390_reload_symref_address):  Likewise.
	(s390_secondary_reload): Vector memory instructions only support
	short displacements.  Rename reload*_nonoffmem* to reload*_la*.
	(s390_emit_ccraw_jump): New function.
	(s390_expand_vec_strlen): New function.
	(s390_expand_vec_compare): New function.
	(s390_expand_vcond): New function.
	(s390_expand_vec_init): New function.
	(s390_dwarf_frame_reg_mode): New function.
	(print_operand): Handle addresses with 'O' and 'R' constraints.
	(NR_C_MODES, constant_modes): Add vector modes.
	(s390_output_pool_entry): Handle vector constants.
	(s390_hard_regno_mode_ok): Handle vector registers.
	(s390_class_max_nregs): Likewise.
	(s390_cannot_change_mode_class): New function.
	(s390_invalid_arg_for_unprototyped_fn): New function.
	(s390_function_arg_vector): New function.
	(s390_function_arg_float): Remove size variable.
	(s390_pass_by_reference): Handle vector arguments.
	(s390_function_arg_advance): Likewise.
	(s390_function_arg): Likewise.
	(s390_return_in_memory): Vector values are returned in a VR if
	possible.
	(s390_function_and_libcall_value): Handle vector arguments.
	(s390_gimplify_va_arg): Likewise.
	(s390_call_saved_register_used): Consider the arguments named.
	(s390_conditional_register_usage): Disable v16-v31 for non-vec
	targets.
	(s390_preferred_simd_mode): New function.
	(s390_support_vector_misalignment): New function.
	(s390_vector_alignment): New function.
	(TARGET_STRICT_ARGUMENT_NAMING, TARGET_DWARF_FRAME_REG_MODE)
	(TARGET_VECTOR_MODE_SUPPORTED_P)
	(TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN)
	(TARGET_VECTORIZE_PREFERRED_SIMD_MODE)
	(TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT)
	(TARGET_VECTOR_ALIGNMENT): Define target macro.
	* config/s390/s390.h (FUNCTION_ARG_PADDING): Define macro.
	(FIRST_PSEUDO_REGISTER): Increase value.
	(VECTOR_NOFP_REGNO_P, VECTOR_REGNO_P, VECTOR_NOFP_REG_P)
	(VECTOR_REG_P): Define macros.
	(FIXED_REGISTERS, CALL_USED_REGISTERS)
	(CALL_REALLY_USED_REGISTERS, REG_ALLOC_ORDER)
	(HARD_REGNO_CALL_PART_CLOBBERED, REG_CLASS_NAMES)
	(FUNCTION_ARG_REGNO_P, FUNCTION_VALUE_REGNO_P, REGISTER_NAMES):
	Add vector registers.
	(CANNOT_CHANGE_MODE_CLASS): Call C function.
	(enum reg_class): Add VEC_REGS, ADDR_VEC_REGS, GENERAL_VEC_REGS.
	(SECONDARY_MEMORY_NEEDED): Allow SF<->SI mode moves without
	memory.
	(DBX_REGISTER_NUMBER, FIRST_VEC_ARG_REGNO, LAST_VEC_ARG_REGNO)
	(SHORT_DISP_IN_RANGE, VECTOR_STORE_FLAG_VALUE): Define macro.
	* config/s390/s390.md (UNSPEC_VEC_*): New constants.
	(VR*_REGNUM): New constants.
	(ALL): New mode iterator.
	(INTALL): Remove mode iterator.
	Include vector.md.
	(movti): Implement TImode moves for VRs.
	Disable TImode splitter for VR targets.
	Implement splitting TImode GPR<->VR moves.
	(reload*_tomem_z10, reload*_toreg_z10): Replace INTALL with ALL.
	(reload<mode>_nonoffmem_in, reload<mode>_nonoffmem_out): Rename to
	reload<mode>_la_in, reload<mode>_la_out.
	(*movdi_64, *movsi_zarch, *movhi, *movqi, *mov<mode>_64dfp)
	(*mov<mode>_64, *mov<mode>_31): Add vector instructions.
	(TD/TF mode splitter): Enable for GPRs only (formerly !FP).
	(mov<mode> SF SD): Prefer lder, lde for loading.
	Add lrl and strl instructions.
	Add vector instructions.
	(strlen<mode>): Rename old strlen<mode> to strlen_srst<mode>.
	Call s390_expand_vec_strlen on z13.
	(*cc_to_int): Change predicate to nonimmediate_operand.
	(addti3): Rename to *addti3.  New expander.
	(subti3): Rename to *subti3.  New expander.
	* config/s390/vector.md: New file.

From-SVN: r223395
This commit is contained in:
Andreas Krebbel 2015-05-19 17:26:35 +00:00 committed by Andreas Krebbel
parent 55ac540cd6
commit 085261c804
9 changed files with 2812 additions and 260 deletions

View File

@ -1,3 +1,102 @@
2015-05-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/constraints.md (j00, jm1, jxx, jyy, v): New
constraints.
* config/s390/predicates.md (const0_operand, constm1_operand)
(constable_operand): Accept vector operands.
* config/s390/s390-modes.def: Add supported vector modes.
* config/s390/s390-protos.h (s390_cannot_change_mode_class)
(s390_function_arg_vector, s390_contiguous_bitmask_vector_p)
(s390_bytemask_vector_p, s390_expand_vec_strlen)
(s390_expand_vec_compare, s390_expand_vcond)
(s390_expand_vec_init): Add prototypes.
* config/s390/s390.c (VEC_ARG_NUM_REG): New macro.
(s390_vector_mode_supported_p): New function.
(s390_contiguous_bitmask_p): Mask out the irrelevant bits.
(s390_contiguous_bitmask_vector_p): New function.
(s390_bytemask_vector_p): New function.
(s390_split_ok_p): Vector regs don't work either.
(regclass_map): Add VEC_REGS.
(s390_legitimate_constant_p): Handle vector constants.
(s390_cannot_force_const_mem): Handle CONST_VECTOR.
(legitimate_reload_vector_constant_p): New function.
(s390_preferred_reload_class): Handle CONST_VECTOR.
(s390_reload_symref_address): Likewise.
(s390_secondary_reload): Vector memory instructions only support
short displacements. Rename reload*_nonoffmem* to reload*_la*.
(s390_emit_ccraw_jump): New function.
(s390_expand_vec_strlen): New function.
(s390_expand_vec_compare): New function.
(s390_expand_vcond): New function.
(s390_expand_vec_init): New function.
(s390_dwarf_frame_reg_mode): New function.
(print_operand): Handle addresses with 'O' and 'R' constraints.
(NR_C_MODES, constant_modes): Add vector modes.
(s390_output_pool_entry): Handle vector constants.
(s390_hard_regno_mode_ok): Handle vector registers.
(s390_class_max_nregs): Likewise.
(s390_cannot_change_mode_class): New function.
(s390_invalid_arg_for_unprototyped_fn): New function.
(s390_function_arg_vector): New function.
(s390_function_arg_float): Remove size variable.
(s390_pass_by_reference): Handle vector arguments.
(s390_function_arg_advance): Likewise.
(s390_function_arg): Likewise.
(s390_return_in_memory): Vector values are returned in a VR if
possible.
(s390_function_and_libcall_value): Handle vector arguments.
(s390_gimplify_va_arg): Likewise.
(s390_call_saved_register_used): Consider the arguments named.
(s390_conditional_register_usage): Disable v16-v31 for non-vec
targets.
(s390_preferred_simd_mode): New function.
(s390_support_vector_misalignment): New function.
(s390_vector_alignment): New function.
(TARGET_STRICT_ARGUMENT_NAMING, TARGET_DWARF_FRAME_REG_MODE)
(TARGET_VECTOR_MODE_SUPPORTED_P)
(TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN)
(TARGET_VECTORIZE_PREFERRED_SIMD_MODE)
(TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT)
(TARGET_VECTOR_ALIGNMENT): Define target macro.
* config/s390/s390.h (FUNCTION_ARG_PADDING): Define macro.
(FIRST_PSEUDO_REGISTER): Increase value.
(VECTOR_NOFP_REGNO_P, VECTOR_REGNO_P, VECTOR_NOFP_REG_P)
(VECTOR_REG_P): Define macros.
(FIXED_REGISTERS, CALL_USED_REGISTERS)
(CALL_REALLY_USED_REGISTERS, REG_ALLOC_ORDER)
(HARD_REGNO_CALL_PART_CLOBBERED, REG_CLASS_NAMES)
(FUNCTION_ARG_REGNO_P, FUNCTION_VALUE_REGNO_P, REGISTER_NAMES):
Add vector registers.
(CANNOT_CHANGE_MODE_CLASS): Call C function.
(enum reg_class): Add VEC_REGS, ADDR_VEC_REGS, GENERAL_VEC_REGS.
(SECONDARY_MEMORY_NEEDED): Allow SF<->SI mode moves without
memory.
(DBX_REGISTER_NUMBER, FIRST_VEC_ARG_REGNO, LAST_VEC_ARG_REGNO)
(SHORT_DISP_IN_RANGE, VECTOR_STORE_FLAG_VALUE): Define macro.
* config/s390/s390.md (UNSPEC_VEC_*): New constants.
(VR*_REGNUM): New constants.
(ALL): New mode iterator.
(INTALL): Remove mode iterator.
Include vector.md.
(movti): Implement TImode moves for VRs.
Disable TImode splitter for VR targets.
Implement splitting TImode GPR<->VR moves.
(reload*_tomem_z10, reload*_toreg_z10): Replace INTALL with ALL.
(reload<mode>_nonoffmem_in, reload<mode>_nonoffmem_out): Rename to
reload<mode>_la_in, reload<mode>_la_out.
(*movdi_64, *movsi_zarch, *movhi, *movqi, *mov<mode>_64dfp)
(*mov<mode>_64, *mov<mode>_31): Add vector instructions.
(TD/TF mode splitter): Enable for GPRs only (formerly !FP).
(mov<mode> SF SD): Prefer lder, lde for loading.
Add lrl and strl instructions.
Add vector instructions.
(strlen<mode>): Rename old strlen<mode> to strlen_srst<mode>.
Call s390_expand_vec_strlen on z13.
(*cc_to_int): Change predicate to nonimmediate_operand.
(addti3): Rename to *addti3. New expander.
(subti3): Rename to *subti3. New expander.
* config/s390/vector.md: New file.
2015-05-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* common/config/s390/s390-common.c (processor_flags_table): Add

View File

@ -29,7 +29,13 @@
;; c -- Condition code register 33.
;; d -- Any register from 0 to 15.
;; f -- Floating point registers.
;; j -- Multiple letter constraint for constant scalar and vector values
;; j00: constant zero scalar or vector
;; jm1: constant scalar or vector with all bits set
;; jxx: contiguous bitmask of 0 or 1 in all vector elements
;; jyy: constant consisting of byte chunks being either 0 or 0xff
;; t -- Access registers 36 and 37.
;; v -- Vector registers v0-v31.
;; C -- A signed 8-bit constant (-128..127)
;; D -- An unsigned 16-bit constant (0..65535)
;; G -- Const double zero operand
@ -102,6 +108,23 @@
"FP_REGS"
"Floating point registers")
(define_constraint "j00"
"Zero scalar or vector constant"
(match_test "op == CONST0_RTX (GET_MODE (op))"))
(define_constraint "jm1"
"All one bit scalar or vector constant"
(match_test "op == CONSTM1_RTX (GET_MODE (op))"))
(define_constraint "jxx"
"@internal"
(and (match_code "const_vector")
(match_test "s390_contiguous_bitmask_vector_p (op, NULL, NULL)")))
(define_constraint "jyy"
"@internal"
(and (match_code "const_vector")
(match_test "s390_bytemask_vector_p (op, NULL)")))
(define_register_constraint "t"
"ACCESS_REGS"
@ -109,6 +132,11 @@
Access registers 36 and 37")
(define_register_constraint "v"
"VEC_REGS"
"Vector registers v0-v31")
;;
;; General constraints for constants.
;;

View File

@ -24,16 +24,20 @@
;; operands --------------------------------------------------------------
;; Return true if OP a (const_int 0) operand.
;; Return true if OP a const 0 operand (int/float/vector).
(define_predicate "const0_operand"
(and (match_code "const_int, const_double")
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (mode)")))
;; Return true if OP an all ones operand (int/float/vector).
(define_predicate "constm1_operand"
(and (match_code "const_int, const_double,const_vector")
(match_test "op == CONSTM1_RTX (mode)")))
;; Return true if OP is constant.
(define_special_predicate "consttable_operand"
(and (match_code "symbol_ref, label_ref, const, const_int, const_double")
(and (match_code "symbol_ref, label_ref, const, const_int, const_double, const_vector")
(match_test "CONSTANT_P (op)")))
;; Return true if OP is a valid S-type operand.

View File

@ -181,3 +181,24 @@ CC_MODE (CCT1);
CC_MODE (CCT2);
CC_MODE (CCT3);
CC_MODE (CCRAW);
/* Vector modes. */
VECTOR_MODES (INT, 2); /* V2QI */
VECTOR_MODES (INT, 4); /* V4QI V2HI */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
VECTOR_MODE (FLOAT, SF, 2); /* V2SF */
VECTOR_MODE (FLOAT, SF, 4); /* V4SF */
VECTOR_MODE (FLOAT, DF, 2); /* V2DF */
VECTOR_MODE (INT, QI, 1); /* V1QI */
VECTOR_MODE (INT, HI, 1); /* V1HI */
VECTOR_MODE (INT, SI, 1); /* V1SI */
VECTOR_MODE (INT, DI, 1); /* V1DI */
VECTOR_MODE (INT, TI, 1); /* V1TI */
VECTOR_MODE (FLOAT, SF, 1); /* V1SF */
VECTOR_MODE (FLOAT, DF, 1); /* V1DF */
VECTOR_MODE (FLOAT, TF, 1); /* V1TF */

View File

@ -43,6 +43,9 @@ extern void s390_set_has_landing_pad_p (bool);
extern bool s390_hard_regno_mode_ok (unsigned int, machine_mode);
extern bool s390_hard_regno_rename_ok (unsigned int, unsigned int);
extern int s390_class_max_nregs (enum reg_class, machine_mode);
extern int s390_cannot_change_mode_class (machine_mode, machine_mode,
enum reg_class);
extern bool s390_function_arg_vector (machine_mode, const_tree);
#ifdef RTX_CODE
extern int s390_extra_constraint_str (rtx, int, const char *);
@ -51,6 +54,8 @@ extern int s390_const_double_ok_for_constraint_p (rtx, int, const char *);
extern int s390_single_part (rtx, machine_mode, machine_mode, int);
extern unsigned HOST_WIDE_INT s390_extract_part (rtx, machine_mode, int);
extern bool s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT, int, int *, int *);
extern bool s390_contiguous_bitmask_vector_p (rtx, int *, int *);
extern bool s390_bytemask_vector_p (rtx, unsigned *);
extern bool s390_split_ok_p (rtx, rtx, machine_mode, int);
extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT);
extern bool s390_offset_p (rtx, rtx, rtx);
@ -83,6 +88,7 @@ extern void s390_load_address (rtx, rtx);
extern bool s390_expand_movmem (rtx, rtx, rtx);
extern void s390_expand_setmem (rtx, rtx, rtx);
extern bool s390_expand_cmpmem (rtx, rtx, rtx, rtx);
extern void s390_expand_vec_strlen (rtx, rtx, rtx);
extern bool s390_expand_addcc (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
extern bool s390_expand_insv (rtx, rtx, rtx, rtx);
extern void s390_expand_cs_hqi (machine_mode, rtx, rtx, rtx,
@ -90,6 +96,9 @@ extern void s390_expand_cs_hqi (machine_mode, rtx, rtx, rtx,
extern void s390_expand_atomic (machine_mode, enum rtx_code,
rtx, rtx, rtx, bool);
extern void s390_expand_tbegin (rtx, rtx, rtx, bool);
extern void s390_expand_vec_compare (rtx, enum rtx_code, rtx, rtx);
extern void s390_expand_vcond (rtx, rtx, rtx, enum rtx_code, rtx, rtx);
extern void s390_expand_vec_init (rtx, rtx);
extern rtx s390_return_addr_rtx (int, rtx);
extern rtx s390_back_chain_rtx (void);
extern rtx_insn *s390_emit_call (rtx, rtx, rtx, rtx);

File diff suppressed because it is too large Load Diff

View File

@ -199,6 +199,13 @@ enum processor_flags
#define STACK_SIZE_MODE (Pmode)
/* Vector arguments are left-justified when placed on the stack during
parameter passing. */
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(s390_function_arg_vector ((MODE), (TYPE)) \
? upward \
: DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE)))
#ifndef IN_LIBGCC2
/* Width of a word, in units (bytes). */
@ -296,9 +303,11 @@ enum processor_flags
Reg 35: Return address pointer
Registers 36 and 37 are mapped to access registers
0 and 1, used to implement thread-local storage. */
0 and 1, used to implement thread-local storage.
#define FIRST_PSEUDO_REGISTER 38
Reg 38-53: Vector registers v16-v31 */
#define FIRST_PSEUDO_REGISTER 54
/* Standard register usage. */
#define GENERAL_REGNO_P(N) ((int)(N) >= 0 && (N) < 16)
@ -307,6 +316,8 @@ enum processor_flags
#define CC_REGNO_P(N) ((N) == 33)
#define FRAME_REGNO_P(N) ((N) == 32 || (N) == 34 || (N) == 35)
#define ACCESS_REGNO_P(N) ((N) == 36 || (N) == 37)
#define VECTOR_NOFP_REGNO_P(N) ((N) >= 38 && (N) <= 53)
#define VECTOR_REGNO_P(N) (FP_REGNO_P (N) || VECTOR_NOFP_REGNO_P (N))
#define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
#define ADDR_REG_P(X) (REG_P (X) && ADDR_REGNO_P (REGNO (X)))
@ -314,6 +325,8 @@ enum processor_flags
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
#define FRAME_REG_P(X) (REG_P (X) && FRAME_REGNO_P (REGNO (X)))
#define ACCESS_REG_P(X) (REG_P (X) && ACCESS_REGNO_P (REGNO (X)))
#define VECTOR_NOFP_REG_P(X) (REG_P (X) && VECTOR_NOFP_REGNO_P (REGNO (X)))
#define VECTOR_REG_P(X) (REG_P (X) && VECTOR_REGNO_P (REGNO (X)))
/* Set up fixed registers and calling convention:
@ -328,7 +341,9 @@ enum processor_flags
On 31-bit, FPRs 18-19 are call-clobbered;
on 64-bit, FPRs 24-31 are call-clobbered.
The remaining FPRs are call-saved. */
The remaining FPRs are call-saved.
All non-FP vector registers are call-clobbered v16-v31. */
#define FIXED_REGISTERS \
{ 0, 0, 0, 0, \
@ -340,7 +355,11 @@ enum processor_flags
0, 0, 0, 0, \
0, 0, 0, 0, \
1, 1, 1, 1, \
1, 1 }
1, 1, \
0, 0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, 0 }
#define CALL_USED_REGISTERS \
{ 1, 1, 1, 1, \
@ -352,26 +371,35 @@ enum processor_flags
1, 1, 1, 1, \
1, 1, 1, 1, \
1, 1, 1, 1, \
1, 1 }
1, 1, \
1, 1, 1, 1, \
1, 1, 1, 1, \
1, 1, 1, 1, \
1, 1, 1, 1 }
#define CALL_REALLY_USED_REGISTERS \
{ 1, 1, 1, 1, \
{ 1, 1, 1, 1, /* r0 - r15 */ \
1, 1, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, 0, \
1, 1, 1, 1, /* f0 (16) - f15 (31) */ \
1, 1, 1, 1, \
1, 1, 1, 1, \
1, 1, 1, 1, \
1, 1, 1, 1, \
1, 1, 1, 1, /* arg, cc, fp, ret addr */ \
0, 0, /* a0 (36), a1 (37) */ \
1, 1, 1, 1, /* v16 (38) - v23 (45) */ \
1, 1, 1, 1, \
0, 0 }
1, 1, 1, 1, /* v24 (46) - v31 (53) */ \
1, 1, 1, 1 }
/* Preferred register allocation order. */
#define REG_ALLOC_ORDER \
{ 1, 2, 3, 4, 5, 0, 12, 11, 10, 9, 8, 7, 6, 14, 13, \
16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26, 27, 28, 29, 30, 31, \
15, 32, 33, 34, 35, 36, 37 }
#define REG_ALLOC_ORDER \
{ 1, 2, 3, 4, 5, 0, 12, 11, 10, 9, 8, 7, 6, 14, 13, \
16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26, 27, 28, 29, 30, 31, \
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, \
15, 32, 33, 34, 35, 36, 37 }
/* Fitting values into registers. */
@ -411,26 +439,22 @@ enum processor_flags
but conforms to the 31-bit ABI, GPRs can hold 8 bytes;
the ABI guarantees only that the lower 4 bytes are
saved across calls, however. */
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
(!TARGET_64BIT && TARGET_ZARCH \
&& GET_MODE_SIZE (MODE) > 4 \
&& (((REGNO) >= 6 && (REGNO) <= 15) || (REGNO) == 32))
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
((!TARGET_64BIT && TARGET_ZARCH \
&& GET_MODE_SIZE (MODE) > 4 \
&& (((REGNO) >= 6 && (REGNO) <= 15) || (REGNO) == 32)) \
|| (TARGET_VX \
&& GET_MODE_SIZE (MODE) > 8 \
&& (((TARGET_64BIT && (REGNO) >= 24 && (REGNO) <= 31)) \
|| (!TARGET_64BIT && ((REGNO) == 18 || (REGNO) == 19)))))
/* Maximum number of registers to represent a value of mode MODE
in a register of class CLASS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
s390_class_max_nregs ((CLASS), (MODE))
/* If a 4-byte value is loaded into a FPR, it is placed into the
*upper* half of the register, not the lower. Therefore, we
cannot use SUBREGs to switch between modes in FP registers.
Likewise for access registers, since they have only half the
word size on 64-bit. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? ((reg_classes_intersect_p (FP_REGS, CLASS) \
&& (GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8)) \
|| reg_classes_intersect_p (ACCESS_REGS, CLASS)) : 0)
s390_cannot_change_mode_class ((FROM), (TO), (CLASS))
/* Register classes. */
@ -458,6 +482,7 @@ enum reg_class
NO_REGS, CC_REGS, ADDR_REGS, GENERAL_REGS, ACCESS_REGS,
ADDR_CC_REGS, GENERAL_CC_REGS,
FP_REGS, ADDR_FP_REGS, GENERAL_FP_REGS,
VEC_REGS, ADDR_VEC_REGS, GENERAL_VEC_REGS,
ALL_REGS, LIM_REG_CLASSES
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
@ -465,11 +490,13 @@ enum reg_class
#define REG_CLASS_NAMES \
{ "NO_REGS", "CC_REGS", "ADDR_REGS", "GENERAL_REGS", "ACCESS_REGS", \
"ADDR_CC_REGS", "GENERAL_CC_REGS", \
"FP_REGS", "ADDR_FP_REGS", "GENERAL_FP_REGS", "ALL_REGS" }
"FP_REGS", "ADDR_FP_REGS", "GENERAL_FP_REGS", \
"VEC_REGS", "ADDR_VEC_REGS", "GENERAL_VEC_REGS", \
"ALL_REGS" }
/* Class -> register mapping. */
#define REG_CLASS_CONTENTS \
{ \
#define REG_CLASS_CONTENTS \
{ \
{ 0x00000000, 0x00000000 }, /* NO_REGS */ \
{ 0x00000000, 0x00000002 }, /* CC_REGS */ \
{ 0x0000fffe, 0x0000000d }, /* ADDR_REGS */ \
@ -480,7 +507,10 @@ enum reg_class
{ 0xffff0000, 0x00000000 }, /* FP_REGS */ \
{ 0xfffffffe, 0x0000000d }, /* ADDR_FP_REGS */ \
{ 0xffffffff, 0x0000000d }, /* GENERAL_FP_REGS */ \
{ 0xffffffff, 0x0000003f }, /* ALL_REGS */ \
{ 0xffff0000, 0x003fffc0 }, /* VEC_REGS */ \
{ 0xfffffffe, 0x003fffcd }, /* ADDR_VEC_REGS */ \
{ 0xffffffff, 0x003fffcd }, /* GENERAL_VEC_REGS */ \
{ 0xffffffff, 0x003fffff }, /* ALL_REGS */ \
}
/* In some case register allocation order is not enough for IRA to
@ -511,14 +541,27 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO)
/* We need secondary memory to move data between GPRs and FPRs. With
DFP the ldgr lgdr instructions are available. But these
instructions do not handle GPR pairs so it is not possible for 31
bit. */
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
((CLASS1) != (CLASS2) \
&& ((CLASS1) == FP_REGS || (CLASS2) == FP_REGS) \
&& (!TARGET_DFP || !TARGET_64BIT || GET_MODE_SIZE (MODE) != 8))
/* We need secondary memory to move data between GPRs and FPRs.
- With DFP the ldgr lgdr instructions are available. Due to the
different alignment we cannot use them for SFmode. For 31 bit a
64 bit value in GPR would be a register pair so here we still
need to go via memory.
- With z13 we can do the SF/SImode moves with vlgvf. Due to the
overlapping of FPRs and VRs we still disallow TF/TD modes to be
in full VRs so as before also on z13 we do these moves via
memory.
FIXME: Should we try splitting it into two vlgvg's/vlvg's instead? */
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
(((reg_classes_intersect_p (CLASS1, VEC_REGS) \
&& reg_classes_intersect_p (CLASS2, GENERAL_REGS)) \
|| (reg_classes_intersect_p (CLASS1, GENERAL_REGS) \
&& reg_classes_intersect_p (CLASS2, VEC_REGS))) \
&& (!TARGET_DFP || !TARGET_64BIT || GET_MODE_SIZE (MODE) != 8) \
&& (!TARGET_VX || (SCALAR_FLOAT_MODE_P (MODE) \
&& GET_MODE_SIZE (MODE) > 8)))
/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit
because the movsi and movsf patterns don't handle r/f moves. */
@ -612,6 +655,11 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
/* Let the assembler generate debug line info. */
#define DWARF2_ASM_LINE_DEBUG_INFO 1
/* Define the dwarf register mapping.
v16-v31 -> 68-83
rX -> X otherwise */
#define DBX_REGISTER_NUMBER(regno) \
((regno >= 38 && regno <= 53) ? regno + 30 : regno)
/* Frame registers. */
@ -659,21 +707,29 @@ typedef struct s390_arg_structure
{
int gprs; /* gpr so far */
int fprs; /* fpr so far */
int vrs; /* vr so far */
}
CUMULATIVE_ARGS;
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, NN, N_NAMED_ARGS) \
((CUM).gprs=0, (CUM).fprs=0)
((CUM).gprs=0, (CUM).fprs=0, (CUM).vrs=0)
#define FIRST_VEC_ARG_REGNO 46
#define LAST_VEC_ARG_REGNO 53
/* Arguments can be placed in general registers 2 to 6, or in floating
point registers 0 and 2 for 31 bit and fprs 0, 2, 4 and 6 for 64
bit. */
#define FUNCTION_ARG_REGNO_P(N) (((N) >=2 && (N) <7) || \
(N) == 16 || (N) == 17 || (TARGET_64BIT && ((N) == 18 || (N) == 19)))
#define FUNCTION_ARG_REGNO_P(N) \
(((N) >=2 && (N) < 7) || (N) == 16 || (N) == 17 \
|| (TARGET_64BIT && ((N) == 18 || (N) == 19)) \
|| (TARGET_VX && ((N) >= FIRST_VEC_ARG_REGNO && (N) <= LAST_VEC_ARG_REGNO)))
/* Only gpr 2 and fpr 0 are ever used as return registers. */
#define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16)
/* Only gpr 2, fpr 0, and v24 are ever used as return registers. */
#define FUNCTION_VALUE_REGNO_P(N) \
((N) == 2 || (N) == 16 \
|| (TARGET_VX && (N) == FIRST_VEC_ARG_REGNO))
/* Function entry and exit. */
@ -833,12 +889,20 @@ do { \
/* How to refer to registers in assembler output. This sequence is
indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
{ "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \
"%f0", "%f2", "%f4", "%f6", "%f1", "%f3", "%f5", "%f7", \
"%f8", "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15", \
"%ap", "%cc", "%fp", "%rp", "%a0", "%a1" \
}
{ "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \
"%f0", "%f2", "%f4", "%f6", "%f1", "%f3", "%f5", "%f7", \
"%f8", "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15", \
"%ap", "%cc", "%fp", "%rp", "%a0", "%a1", \
"%v16", "%v18", "%v20", "%v22", "%v17", "%v19", "%v21", "%v23", \
"%v24", "%v26", "%v28", "%v30", "%v25", "%v27", "%v29", "%v31" \
}
#define ADDITIONAL_REGISTER_NAMES \
{ { "v0", 16 }, { "v2", 17 }, { "v4", 18 }, { "v6", 19 }, \
{ "v1", 20 }, { "v3", 21 }, { "v5", 22 }, { "v7", 23 }, \
{ "v8", 24 }, { "v10", 25 }, { "v12", 26 }, { "v14", 27 }, \
{ "v9", 28 }, { "v11", 29 }, { "v13", 30 }, { "v15", 31 } };
/* Print operand X (an rtx) in assembler syntax to file FILE. */
#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
@ -908,13 +972,21 @@ do { \
#define SYMBOL_REF_NOT_NATURALLY_ALIGNED_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_NOT_NATURALLY_ALIGNED))
/* Check whether integer displacement is in range for a short displacement. */
#define SHORT_DISP_IN_RANGE(d) ((d) >= 0 && (d) <= 4095)
/* Check whether integer displacement is in range. */
#define DISP_IN_RANGE(d) \
(TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
: ((d) >= 0 && (d) <= 4095))
: SHORT_DISP_IN_RANGE(d))
/* Reads can reuse write prefetches, used by tree-ssa-prefetch-loops.c. */
#define READ_CAN_USE_WRITE_PREFETCH 1
extern const int processor_flags_table[];
#endif
/* The truth element value for vector comparisons. Our instructions
always generate -1 in that case. */
#define VECTOR_STORE_FLAG_VALUE(MODE) CONSTM1_RTX (GET_MODE_INNER (MODE))
#endif /* S390_H */

View File

@ -125,7 +125,23 @@
UNSPEC_FPINT_CEIL
UNSPEC_FPINT_NEARBYINT
UNSPEC_FPINT_RINT
])
; Vector
UNSPEC_VEC_EXTRACT
UNSPEC_VEC_SET
UNSPEC_VEC_PERM
UNSPEC_VEC_SRLB
UNSPEC_VEC_GENBYTEMASK
UNSPEC_VEC_VSUM
UNSPEC_VEC_VSUMG
UNSPEC_VEC_SMULT_EVEN
UNSPEC_VEC_UMULT_EVEN
UNSPEC_VEC_SMULT_ODD
UNSPEC_VEC_UMULT_ODD
UNSPEC_VEC_LOAD_LEN
UNSPEC_VEC_VFENE
UNSPEC_VEC_VFENECC
])
;;
;; UNSPEC_VOLATILE usage
@ -216,6 +232,11 @@
(FPR13_REGNUM 30)
(FPR14_REGNUM 27)
(FPR15_REGNUM 31)
(VR0_REGNUM 16)
(VR16_REGNUM 38)
(VR23_REGNUM 45)
(VR24_REGNUM 46)
(VR31_REGNUM 53)
])
;;
@ -246,7 +267,7 @@
;; Used to determine defaults for length and other attribute values.
(define_attr "op_type"
"NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR,SIL,RRS,RIS"
"NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX"
(const_string "NN"))
;; Instruction type attribute used for scheduling.
@ -403,12 +424,13 @@
;; Iterators
(define_mode_iterator ALL [TI DI SI HI QI TF DF SF TD DD SD V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
;; These mode iterators allow floating point patterns to be generated from the
;; same template.
(define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
(SD "TARGET_HARD_DFP")])
(define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
(define_mode_iterator FPALL [TF DF SF TD DD SD])
(define_mode_iterator BFP [TF DF SF])
(define_mode_iterator DFP [TD DD])
(define_mode_iterator DFP_ALL [TD DD SD])
@ -444,7 +466,6 @@
;; This mode iterator allows the integer patterns to be defined from the
;; same template.
(define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
(define_mode_iterator INTALL [TI DI SI HI QI])
(define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
@ -614,6 +635,8 @@
;; Allow return and simple_return to be defined from a single template.
(define_code_iterator ANY_RETURN [return simple_return])
(include "vector.md")
;;
;;- Compare instructions.
;;
@ -1246,17 +1269,27 @@
; movti instruction pattern(s).
;
; FIXME: More constants are possible by enabling jxx, jyy constraints
; for TImode (use double-int for the calculations)
(define_insn "movti"
[(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o")
(match_operand:TI 1 "general_operand" "QS,d,dPRT,d"))]
[(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,v, v, v,v,d, v,QR, d,o")
(match_operand:TI 1 "general_operand" "QS, d,v,j00,jm1,d,v,QR, v,dPRT,d"))]
"TARGET_ZARCH"
"@
lmg\t%0,%N0,%S1
stmg\t%1,%N1,%S0
vlr\t%v0,%v1
vzero\t%v0
vone\t%v0
vlvgp\t%v0,%1,%N1
#
vl\t%v0,%1
vst\t%v1,%0
#
#"
[(set_attr "op_type" "RSY,RSY,*,*")
(set_attr "type" "lm,stm,*,*")])
[(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
(set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
(set_attr "cpu_facility" "*,*,vec,vec,vec,vec,vec,vec,vec,*,*")])
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
@ -1286,10 +1319,14 @@
operands[5] = operand_subword (operands[1], 0, 0, TImode);
})
; Use part of the TImode target reg to perform the address
; calculation. If the TImode value is supposed to be copied into a VR
; this splitter is not necessary.
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(match_operand:TI 1 "memory_operand" ""))]
"TARGET_ZARCH && reload_completed
&& !VECTOR_REG_P (operands[0])
&& !s_operand (operands[1], VOIDmode)"
[(set (match_dup 0) (match_dup 1))]
{
@ -1300,6 +1337,25 @@
})
; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
; For the higher order bits we do simply a DImode move while the
; second part is done via vec extract. Both will end up as vlgvg.
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(match_operand:TI 1 "register_operand" ""))]
"TARGET_VX && reload_completed
&& GENERAL_REG_P (operands[0])
&& VECTOR_REG_P (operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
UNSPEC_VEC_EXTRACT))]
{
operands[2] = operand_subword (operands[0], 0, 0, TImode);
operands[3] = operand_subword (operands[0], 1, 0, TImode);
operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
})
;
; Patterns used for secondary reloads
;
@ -1308,40 +1364,20 @@
; Unfortunately there is no such variant for QI, TI and FP mode moves.
; These patterns are also used for unaligned SI and DI accesses.
(define_expand "reload<INTALL:mode><P:mode>_tomem_z10"
[(parallel [(match_operand:INTALL 0 "memory_operand" "")
(match_operand:INTALL 1 "register_operand" "=d")
(match_operand:P 2 "register_operand" "=&a")])]
(define_expand "reload<ALL:mode><P:mode>_tomem_z10"
[(parallel [(match_operand:ALL 0 "memory_operand" "")
(match_operand:ALL 1 "register_operand" "=d")
(match_operand:P 2 "register_operand" "=&a")])]
"TARGET_Z10"
{
s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
DONE;
})
(define_expand "reload<INTALL:mode><P:mode>_toreg_z10"
[(parallel [(match_operand:INTALL 0 "register_operand" "=d")
(match_operand:INTALL 1 "memory_operand" "")
(match_operand:P 2 "register_operand" "=a")])]
"TARGET_Z10"
{
s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
DONE;
})
(define_expand "reload<FPALL:mode><P:mode>_tomem_z10"
[(parallel [(match_operand:FPALL 0 "memory_operand" "")
(match_operand:FPALL 1 "register_operand" "=d")
(match_operand:P 2 "register_operand" "=&a")])]
"TARGET_Z10"
{
s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
DONE;
})
(define_expand "reload<FPALL:mode><P:mode>_toreg_z10"
[(parallel [(match_operand:FPALL 0 "register_operand" "=d")
(match_operand:FPALL 1 "memory_operand" "")
(match_operand:P 2 "register_operand" "=a")])]
(define_expand "reload<ALL:mode><P:mode>_toreg_z10"
[(parallel [(match_operand:ALL 0 "register_operand" "=d")
(match_operand:ALL 1 "memory_operand" "")
(match_operand:P 2 "register_operand" "=a")])]
"TARGET_Z10"
{
s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
@ -1370,9 +1406,16 @@
DONE;
})
; Handles assessing a non-offsetable memory address
; Not all the indirect memory access instructions support the full
; format (long disp + index + base). So whenever a move from/to such
; an address is required and the instruction cannot deal with it we do
; a load address into a scratch register first and use this as the new
; base register.
; This in particular is used for:
; - non-offsetable memory accesses for multiword moves
; - full vector reg moves with long displacements
(define_expand "reload<mode>_nonoffmem_in"
(define_expand "reload<mode>_la_in"
[(parallel [(match_operand 0 "register_operand" "")
(match_operand 1 "" "")
(match_operand:P 2 "register_operand" "=&a")])]
@ -1385,7 +1428,7 @@
DONE;
})
(define_expand "reload<mode>_nonoffmem_out"
(define_expand "reload<mode>_la_out"
[(parallel [(match_operand 0 "" "")
(match_operand 1 "register_operand" "")
(match_operand:P 2 "register_operand" "=&a")])]
@ -1438,11 +1481,9 @@
(define_insn "*movdi_64"
[(set (match_operand:DI 0 "nonimmediate_operand"
"=d,d,d,d,d,d,d,d,f,d,d,d,d,d,
RT,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t")
"=d, d, d, d, d, d, d, d,f,d,d,d,d, d,RT,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d, v,QR")
(match_operand:DI 1 "general_operand"
"K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,RT,
d,*f,R,T,*f,*f,d,K,t,d,t,Q"))]
" K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,RT, d, *f, R, T,*f,*f,d,K,t,d,t,Q,K,v,d,v,QR, v"))]
"TARGET_ZARCH"
"@
lghi\t%0,%h1
@ -1470,15 +1511,21 @@
#
#
stam\t%1,%N1,%S0
lam\t%0,%N0,%S1"
lam\t%0,%N0,%S1
vleig\t%v0,%h1,0
vlr\t%v0,%v1
vlvgg\t%v0,%1,0
vlgvg\t%0,%v1,0
vleg\t%v0,%1,0
vsteg\t%v1,%0,0"
[(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS")
RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
(set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,
*,*")
floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
*,*,*,*,*,*,*")
(set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
z10,*,*,*,*,*,longdisp,*,longdisp,
z10,z10,*,*,*,*")
z10,z10,*,*,*,*,vec,vec,vec,vec,vec,vec")
(set_attr "z10prop" "z10_fwd_A1,
z10_fwd_E1,
z10_fwd_E1,
@ -1504,7 +1551,7 @@
*,
*,
*,
*")
*,*,*,*,*,*,*")
])
(define_split
@ -1696,9 +1743,9 @@
(define_insn "*movsi_zarch"
[(set (match_operand:SI 0 "nonimmediate_operand"
"=d,d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t")
"=d, d, d, d,d,d,d,d,d,R,T,!*f,!*f,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,v,v,v,d, v,QR")
(match_operand:SI 1 "general_operand"
"K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,d,K,Q"))]
" K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d, *f, *f, R, R, T,*f,*f,t,d,t,d,K,Q,K,v,d,v,QR, v"))]
"TARGET_ZARCH"
"@
lhi\t%0,%h1
@ -1712,7 +1759,9 @@
ly\t%0,%1
st\t%1,%0
sty\t%1,%0
lder\t%0,%1
ler\t%0,%1
lde\t%0,%1
le\t%0,%1
ley\t%0,%1
ste\t%1,%0
@ -1722,9 +1771,15 @@
stam\t%1,%1,%S0
strl\t%1,%0
mvhi\t%0,%1
lam\t%0,%0,%S1"
lam\t%0,%0,%S1
vleif\t%v0,%h1,0
vlr\t%v0,%v1
vlvgf\t%v0,%1,0
vlgvf\t%0,%v1,0
vlef\t%v0,%1,0
vstef\t%v1,%0,0"
[(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
RR,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS")
RRE,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
(set_attr "type" "*,
*,
*,
@ -1739,6 +1794,8 @@
floadsf,
floadsf,
floadsf,
floadsf,
floadsf,
fstoresf,
fstoresf,
*,
@ -1746,9 +1803,9 @@
*,
larl,
*,
*")
*,*,*,*,*,*,*")
(set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
*,*,longdisp,*,longdisp,*,*,*,z10,z10,*")
vec,*,vec,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vec,vec,vec,vec,vec,vec")
(set_attr "z10prop" "z10_fwd_A1,
z10_fwd_E1,
z10_fwd_E1,
@ -1765,42 +1822,38 @@
*,
*,
*,
*,
*,
z10_super_E1,
z10_super,
*,
z10_rec,
z10_super,
*")])
*,*,*,*,*,*,*")])
(define_insn "*movsi_esa"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t")
(match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
(match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
"!TARGET_ZARCH"
"@
lhi\t%0,%h1
lr\t%0,%1
l\t%0,%1
st\t%1,%0
lder\t%0,%1
ler\t%0,%1
lde\t%0,%1
le\t%0,%1
ste\t%1,%0
ear\t%0,%1
sar\t%0,%1
stam\t%1,%1,%S0
lam\t%0,%0,%S1"
[(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS")
(set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*")
(set_attr "z10prop" "z10_fwd_A1,
z10_fr_E1,
z10_fwd_A3,
z10_rec,
*,
*,
*,
z10_super_E1,
z10_super,
*,
*")
[(set_attr "op_type" "RI,RR,RX,RX,RRE,RR,RXE,RX,RX,RRE,RRE,RS,RS")
(set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
(set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
z10_super,*,*")
(set_attr "cpu_facility" "*,*,*,*,vec,*,vec,*,*,*,*,*,*")
])
(define_peephole2
@ -1910,8 +1963,8 @@
})
(define_insn "*movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q")
(match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K"))]
[(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d, v,QR")
(match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,QR, v"))]
""
"@
lr\t%0,%1
@ -1922,10 +1975,16 @@
sth\t%1,%0
sthy\t%1,%0
sthrl\t%1,%0
mvhhi\t%0,%1"
[(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL")
(set_attr "type" "lr,*,*,*,larl,store,store,store,*")
(set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10")
mvhhi\t%0,%1
vleih\t%v0,%h1,0
vlr\t%v0,%v1
vlvgh\t%v0,%1,0
vlgvh\t%0,%v1,0
vleh\t%v0,%1,0
vsteh\t%v1,%0,0"
[(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
(set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
(set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10,vec,vec,vec,vec,vec,vec")
(set_attr "z10prop" "z10_fr_E1,
z10_fwd_A1,
z10_super_E1,
@ -1934,7 +1993,7 @@
z10_rec,
z10_rec,
z10_rec,
z10_super")])
z10_super,*,*,*,*,*,*")])
(define_peephole2
[(set (match_operand:HI 0 "register_operand" "")
@ -1969,8 +2028,8 @@
})
(define_insn "*movqi"
[(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
(match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q"))]
[(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d, v,QR")
(match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,QR, v"))]
""
"@
lr\t%0,%1
@ -1981,9 +2040,16 @@
stcy\t%1,%0
mvi\t%S0,%b1
mviy\t%S0,%b1
#"
[(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
(set_attr "type" "lr,*,*,*,store,store,store,store,*")
#
vleib\t%v0,%b1,0
vlr\t%v0,%v1
vlvgb\t%v0,%1,0
vlgvb\t%0,%v1,0
vleb\t%v0,%1,0
vsteb\t%v1,%0,0"
[(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
(set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
(set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,vec,vec,vec,vec,vec,vec")
(set_attr "z10prop" "z10_fr_E1,
z10_fwd_A1,
z10_super_E1,
@ -1992,7 +2058,7 @@
z10_rec,
z10_super,
z10_super,
*")])
*,*,*,*,*,*,*")])
(define_peephole2
[(set (match_operand:QI 0 "nonimmediate_operand" "")
@ -2124,7 +2190,7 @@
[(set (match_operand:TD_TF 0 "register_operand" "")
(match_operand:TD_TF 1 "memory_operand" ""))]
"TARGET_ZARCH && reload_completed
&& !FP_REG_P (operands[0])
&& GENERAL_REG_P (operands[0])
&& !s_operand (operands[1], VOIDmode)"
[(set (match_dup 0) (match_dup 1))]
{
@ -2180,9 +2246,9 @@
(define_insn "*mov<mode>_64dfp"
[(set (match_operand:DD_DF 0 "nonimmediate_operand"
"=f,f,f,d,f,f,R,T,d,d, d,RT")
"=f,f,f,d,f,f,R,T,d,d,d, d,b,RT,v,v,d,v,QR")
(match_operand:DD_DF 1 "general_operand"
" G,f,d,f,R,T,f,f,G,d,RT, d"))]
" G,f,d,f,R,T,f,f,G,d,b,RT,d, d,v,d,v,QR,v"))]
"TARGET_DFP"
"@
lzdr\t%0
@ -2195,17 +2261,24 @@
stdy\t%1,%0
lghi\t%0,0
lgr\t%0,%1
lgrl\t%0,%1
lg\t%0,%1
stg\t%1,%0"
[(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RXY,RXY")
stgrl\t%1,%0
stg\t%1,%0
vlr\t%v0,%v1
vlvgg\t%v0,%1,0
vlgvg\t%0,%v1,0
vleg\t%0,%1,0
vsteg\t%1,%0,0"
[(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRS,VRS,VRX,VRX")
(set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
fstoredf,fstoredf,*,lr,load,store")
(set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec")
(set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")])
fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,load,store")
(set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*")
(set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec,vec,vec")])
(define_insn "*mov<mode>_64"
[(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d, d,RT")
(match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,RT, d"))]
[(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d, d,b,RT,v,v,QR")
(match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,RT,d, d,v,QR,v"))]
"TARGET_ZARCH"
"@
lzdr\t%0
@ -2216,13 +2289,18 @@
stdy\t%1,%0
lghi\t%0,0
lgr\t%0,%1
lgrl\t%0,%1
lg\t%0,%1
stg\t%1,%0"
[(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RXY,RXY")
stgrl\t%1,%0
stg\t%1,%0
vlr\t%v0,%v1
vleg\t%v0,%1,0
vsteg\t%v1,%0,0"
[(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRX,VRX")
(set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
fstore<mode>,fstore<mode>,*,lr,load,store")
(set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec")
(set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*")])
fstore<mode>,fstore<mode>,*,lr,load,load,store,store,*,load,store")
(set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*")
(set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec")])
(define_insn "*mov<mode>_31"
[(set (match_operand:DD_DF 0 "nonimmediate_operand"
@ -2295,28 +2373,38 @@
(define_insn "mov<mode>"
[(set (match_operand:SD_SF 0 "nonimmediate_operand"
"=f,f,f,f,R,T,d,d,d,d,R,T")
"=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,QR")
(match_operand:SD_SF 1 "general_operand"
" G,f,R,T,f,f,G,d,R,T,d,d"))]
" G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,QR,v"))]
""
"@
lzer\t%0
lder\t%0,%1
ler\t%0,%1
lde\t%0,%1
le\t%0,%1
ley\t%0,%1
ste\t%1,%0
stey\t%1,%0
lhi\t%0,0
lr\t%0,%1
lrl\t%0,%1
l\t%0,%1
ly\t%0,%1
strl\t%1,%0
st\t%1,%0
sty\t%1,%0"
[(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RR,RX,RXY,RX,RXY")
(set_attr "type" "fsimpsf,fload<mode>,fload<mode>,fload<mode>,
fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
(set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
(set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")])
sty\t%1,%0
vlr\t%v0,%v1
vleif\t%v0,0
vlvgf\t%v0,%1,0
vlgvf\t%0,%v1,0
vleg\t%0,%1,0
vsteg\t%1,%0,0"
[(set_attr "op_type" "RRE,RRE,RR,RXE,RX,RXY,RX,RXY,RI,RR,RIL,RX,RXY,RIL,RX,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
(set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
(set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
(set_attr "cpu_facility" "z196,vec,*,vec,*,*,*,*,*,*,z10,*,*,z10,*,*,vec,vec,vec,vec,vec,vec")])
;
; movcc instruction pattern
@ -2606,6 +2694,22 @@
;
(define_expand "strlen<mode>"
[(match_operand:P 0 "register_operand" "") ; result
(match_operand:BLK 1 "memory_operand" "") ; input string
(match_operand:SI 2 "immediate_operand" "") ; search character
(match_operand:SI 3 "immediate_operand" "")] ; known alignment
""
{
if (!TARGET_VX || operands[2] != const0_rtx)
emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
operands[2], operands[3]));
else
s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
DONE;
})
(define_expand "strlen_srst<mode>"
[(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
(parallel
[(set (match_dup 4)
@ -2915,8 +3019,12 @@
operands[2] = GEN_INT (S390_TDC_INFINITY);
})
; This extracts CC into a GPR properly shifted. The actual IPM
; instruction will be issued by reload. The constraint of operand 1
; forces reload to use a GPR. So reload will issue a movcc insn for
; copying CC into a GPR first.
(define_insn_and_split "*cc_to_int"
[(set (match_operand:SI 0 "register_operand" "=d")
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(unspec:SI [(match_operand 1 "register_operand" "0")]
UNSPEC_CC_TO_INT))]
"operands != NULL"
@ -4667,10 +4775,29 @@
; addti3 instruction pattern(s).
;
(define_insn_and_split "addti3"
[(set (match_operand:TI 0 "register_operand" "=&d")
(define_expand "addti3"
[(parallel
[(set (match_operand:TI 0 "register_operand" "")
(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
(match_operand:TI 2 "general_operand" "") ) )
(clobber (reg:CC CC_REGNUM))])]
"TARGET_ZARCH"
{
/* For z13 we have vaq which doesn't set CC. */
if (TARGET_VX)
{
emit_insn (gen_rtx_SET (operands[0],
gen_rtx_PLUS (TImode,
copy_to_mode_reg (TImode, operands[1]),
copy_to_mode_reg (TImode, operands[2]))));
DONE;
}
})
(define_insn_and_split "*addti3"
[(set (match_operand:TI 0 "register_operand" "=&d")
(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
(match_operand:TI 2 "general_operand" "do") ) )
(match_operand:TI 2 "general_operand" "do") ) )
(clobber (reg:CC CC_REGNUM))]
"TARGET_ZARCH"
"#"
@ -4690,7 +4817,9 @@
operands[5] = operand_subword (operands[2], 0, 0, TImode);
operands[6] = operand_subword (operands[0], 1, 0, TImode);
operands[7] = operand_subword (operands[1], 1, 0, TImode);
operands[8] = operand_subword (operands[2], 1, 0, TImode);")
operands[8] = operand_subword (operands[2], 1, 0, TImode);"
[(set_attr "op_type" "*")
(set_attr "cpu_facility" "*")])
;
; adddi3 instruction pattern(s).
@ -5128,10 +5257,29 @@
; subti3 instruction pattern(s).
;
(define_insn_and_split "subti3"
[(set (match_operand:TI 0 "register_operand" "=&d")
(minus:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:TI 2 "general_operand" "do") ) )
(define_expand "subti3"
[(parallel
[(set (match_operand:TI 0 "register_operand" "")
(minus:TI (match_operand:TI 1 "register_operand" "")
(match_operand:TI 2 "general_operand" "") ) )
(clobber (reg:CC CC_REGNUM))])]
"TARGET_ZARCH"
{
/* For z13 we have vaq which doesn't set CC. */
if (TARGET_VX)
{
emit_insn (gen_rtx_SET (operands[0],
gen_rtx_MINUS (TImode,
operands[1],
copy_to_mode_reg (TImode, operands[2]))));
DONE;
}
})
(define_insn_and_split "*subti3"
[(set (match_operand:TI 0 "register_operand" "=&d")
(minus:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:TI 2 "general_operand" "do") ) )
(clobber (reg:CC CC_REGNUM))]
"TARGET_ZARCH"
"#"
@ -5150,7 +5298,9 @@
operands[5] = operand_subword (operands[2], 0, 0, TImode);
operands[6] = operand_subword (operands[0], 1, 0, TImode);
operands[7] = operand_subword (operands[1], 1, 0, TImode);
operands[8] = operand_subword (operands[2], 1, 0, TImode);")
operands[8] = operand_subword (operands[2], 1, 0, TImode);"
[(set_attr "op_type" "*")
(set_attr "cpu_facility" "*")])
;
; subdi3 instruction pattern(s).

1226
gcc/config/s390/vector.md Normal file

File diff suppressed because it is too large Load Diff