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:
parent
55ac540cd6
commit
085261c804
@ -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
|
||||
|
@ -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.
|
||||
;;
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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
@ -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 */
|
||||
|
@ -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
1226
gcc/config/s390/vector.md
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user