/* Definitions of target machine for GNU compiler, for IBM S/390
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
+ Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
This file is part of GCC.
PROCESSOR_2064_Z900,
PROCESSOR_2084_Z990,
PROCESSOR_2094_Z9_109,
+ PROCESSOR_2097_Z10,
PROCESSOR_max
};
PF_ZARCH = 2,
PF_LONG_DISPLACEMENT = 4,
PF_EXTIMM = 8,
- PF_DFP = 16
+ PF_DFP = 16,
+ PF_Z10 = 32
};
extern enum processor_type s390_tune;
-extern enum processor_flags s390_tune_flags;
+extern int s390_tune_flags;
+
+/* This is necessary to avoid a warning about comparing different enum
+ types. */
+#define s390_tune_attr ((enum attr_cpu)s390_tune)
extern enum processor_type s390_arch;
-extern enum processor_flags s390_arch_flags;
+extern int s390_arch_flags;
+
+/* These flags indicate that the generated code should run on a cpu
+ providing the respective hardware facility regardless of the
+ current cpu mode (ESA or z/Architecture). */
#define TARGET_CPU_IEEE_FLOAT \
(s390_arch_flags & PF_IEEE_FLOAT)
(s390_arch_flags & PF_EXTIMM)
#define TARGET_CPU_DFP \
(s390_arch_flags & PF_DFP)
+#define TARGET_CPU_Z10 \
+ (s390_arch_flags & PF_Z10)
+
+/* These flags indicate that the generated code should run on a cpu
+ providing the respective hardware facility when run in
+ z/Architecture mode. */
#define TARGET_LONG_DISPLACEMENT \
(TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT)
#define TARGET_EXTIMM \
(TARGET_ZARCH && TARGET_CPU_EXTIMM)
#define TARGET_DFP \
- (TARGET_ZARCH && TARGET_CPU_DFP)
+ (TARGET_ZARCH && TARGET_CPU_DFP && TARGET_HARD_FLOAT)
+#define TARGET_Z10 \
+ (TARGET_ZARCH && TARGET_CPU_Z10)
/* Run-time target specification. */
#define CAN_DEBUG_WITHOUT_FP
/* Constants needed to control the TEST DATA CLASS (TDC) instruction. */
-#define S390_TDC_POSITIVE_ZERO (1 << 11)
-#define S390_TDC_NEGATIVE_ZERO (1 << 10)
-#define S390_TDC_POSITIVE_NORMALIZED_NUMBER (1 << 9)
-#define S390_TDC_NEGATIVE_NORMALIZED_NUMBER (1 << 8)
-#define S390_TDC_POSITIVE_DENORMALIZED_NUMBER (1 << 7)
-#define S390_TDC_NEGATIVE_DENORMALIZED_NUMBER (1 << 6)
-#define S390_TDC_POSITIVE_INFINITY (1 << 5)
-#define S390_TDC_NEGATIVE_INFINITY (1 << 4)
-#define S390_TDC_POSITIVE_QUIET_NAN (1 << 3)
-#define S390_TDC_NEGATIVE_QUIET_NAN (1 << 2)
-#define S390_TDC_POSITIVE_SIGNALING_NAN (1 << 1)
-#define S390_TDC_NEGATIVE_SIGNALING_NAN (1 << 0)
-
+#define S390_TDC_POSITIVE_ZERO (1 << 11)
+#define S390_TDC_NEGATIVE_ZERO (1 << 10)
+#define S390_TDC_POSITIVE_NORMALIZED_BFP_NUMBER (1 << 9)
+#define S390_TDC_NEGATIVE_NORMALIZED_BFP_NUMBER (1 << 8)
+#define S390_TDC_POSITIVE_DENORMALIZED_BFP_NUMBER (1 << 7)
+#define S390_TDC_NEGATIVE_DENORMALIZED_BFP_NUMBER (1 << 6)
+#define S390_TDC_POSITIVE_INFINITY (1 << 5)
+#define S390_TDC_NEGATIVE_INFINITY (1 << 4)
+#define S390_TDC_POSITIVE_QUIET_NAN (1 << 3)
+#define S390_TDC_NEGATIVE_QUIET_NAN (1 << 2)
+#define S390_TDC_POSITIVE_SIGNALING_NAN (1 << 1)
+#define S390_TDC_NEGATIVE_SIGNALING_NAN (1 << 0)
+
+/* The following values are different for DFP. */
+#define S390_TDC_POSITIVE_DENORMALIZED_DFP_NUMBER (1 << 9)
+#define S390_TDC_NEGATIVE_DENORMALIZED_DFP_NUMBER (1 << 8)
+#define S390_TDC_POSITIVE_NORMALIZED_DFP_NUMBER (1 << 7)
+#define S390_TDC_NEGATIVE_NORMALIZED_DFP_NUMBER (1 << 6)
+
+/* For signbit, the BFP-DFP-difference makes no difference. */
#define S390_TDC_SIGNBIT_SET (S390_TDC_NEGATIVE_ZERO \
- | S390_TDC_NEGATIVE_NORMALIZED_NUMBER \
- | S390_TDC_NEGATIVE_DENORMALIZED_NUMBER\
+ | S390_TDC_NEGATIVE_NORMALIZED_BFP_NUMBER \
+ | S390_TDC_NEGATIVE_DENORMALIZED_BFP_NUMBER\
| S390_TDC_NEGATIVE_INFINITY \
| S390_TDC_NEGATIVE_QUIET_NAN \
| S390_TDC_NEGATIVE_SIGNALING_NAN )
{ 0xffffffff, 0x0000003f }, /* ALL_REGS */ \
}
+/* The following macro defines cover classes for Integrated Register
+ Allocator. Cover classes is a set of non-intersected register
+ classes covering all hard registers used for register allocation
+ purpose. Any move between two registers of a cover class should be
+ cheaper than load or store of the registers. The macro value is
+ array of register classes with LIM_REG_CLASSES used as the end
+ marker. */
+
+#define IRA_COVER_CLASSES \
+{ \
+ GENERAL_REGS, FP_REGS, CC_REGS, ACCESS_REGS, LIM_REG_CLASSES \
+}
+
+/* In some case register allocation order is not enough for IRA to
+ generate a good code. The following macro (if defined) increases
+ cost of REGNO for a pseudo approximately by pseudo usage frequency
+ multiplied by the macro value.
+
+ We avoid usage of BASE_REGNUM by nonzero macro value because the
+ reload can decide not to use the hard register because some
+ constant was forced to be in memory. */
+#define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) \
+ (regno == BASE_REGNUM ? 0.0 : 0.5)
+
/* Register -> class mapping. */
extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
#define PREFERRED_RELOAD_CLASS(X, CLASS) \
s390_preferred_reload_class ((X), (CLASS))
-/* We need secondary memory to move data between GPRs and FPRs. */
+/* 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 || GET_MODE_SIZE (MODE) != 8))
+ && (!TARGET_DFP || !TARGET_64BIT || 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. */
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'. */
-extern int current_function_outgoing_args_size;
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
- (STACK_POINTER_OFFSET + current_function_outgoing_args_size)
+ (STACK_POINTER_OFFSET + crtl->outgoing_args_size)
/* Offset of first parameter from the argument pointer register value.
We have a fake argument pointer register that points directly to
/* Defining this macro makes __builtin_frame_address(0) and
__builtin_return_address(0) work with -fomit-frame-pointer. */
#define INITIAL_FRAME_ADDRESS_RTX \
- (TARGET_PACKED_STACK ? \
- plus_constant (arg_pointer_rtx, -UNITS_PER_WORD) : \
- plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
+ (plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
/* The return address of the current frame is retrieved
from the initial value of register RETURN_REGNUM.
(TARGET_PACKED_STACK ? \
plus_constant ((FRAME), STACK_POINTER_OFFSET - UNITS_PER_WORD) : (FRAME))
+/* For -mpacked-stack this adds 160 - 8 (96 - 4) to the output of
+ builtin_frame_address. Otherwise arg pointer -
+ STACK_POINTER_OFFSET would be returned for
+ __builtin_frame_address(0) what might result in an address pointing
+ somewhere into the middle of the local variables since the packed
+ stack layout generally does not need all the bytes in the register
+ save area. */
+#define FRAME_ADDR_RTX(FRAME) \
+ DYNAMIC_CHAIN_ADDRESS ((FRAME))
+
#define RETURN_ADDR_RTX(COUNT, FRAME) \
s390_return_addr_rtx ((COUNT), DYNAMIC_CHAIN_ADDRESS ((FRAME)))
/* Frame pointer and argument pointer elimination. */
-#define FRAME_POINTER_REQUIRED 0
-
#define ELIMINABLE_REGS \
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
s390_function_arg (&CUM, MODE, TYPE, NAMED)
-/* Arguments can be placed in general registers 2 to 6,
- or in floating point registers 0 and 2. */
+/* 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)
+ (N) == 16 || (N) == 17 || (TARGET_64BIT && ((N) == 18 || (N) == 19)))
/* Scalar return values. */
/* Maximum number of registers that can appear in a valid memory address. */
#define MAX_REGS_PER_ADDRESS 2
-/* S/390 has no mode dependent addresses. */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
-
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
- valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address. */
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 1)) \
- goto ADDR; \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 0)) \
- goto ADDR; \
-}
-#endif
-
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c. */
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ \
- (X) = legitimize_address (X, OLDX, MODE); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
+/* This definition replaces the formerly used 'm' constraint with a
+ different constraint letter in order to avoid changing semantics of
+ the 'm' constraint when accepting new address formats in
+ TARGET_LEGITIMATE_ADDRESS_P. The constraint letter defined here
+ must not be used in insn definitions or inline assemblies. */
+#define TARGET_MEM_CONSTRAINT 'e'
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c. */
#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
do { \
- rtx new = legitimize_reload_address (AD, MODE, OPNUM, (int)(TYPE)); \
- if (new) \
+ rtx new_rtx = legitimize_reload_address (AD, MODE, OPNUM, (int)(TYPE)); \
+ if (new_rtx) \
{ \
- (AD) = new; \
+ (AD) = new_rtx; \
goto WIN; \
} \
} while (0)
#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
s390_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-extern struct rtx_def *s390_compare_op0, *s390_compare_op1, *s390_compare_emitted;
-
-
/* Relative costs of operations. */
/* On s390, copy between fprs and gprs is expensive. */
/* A C expression for the cost of a branch instruction. A value of 1
is the default; other values are interpreted relative to that. */
-#define BRANCH_COST 1
+#define BRANCH_COST(speed_p, predictable_p) 1
/* Nonzero if access to memory by bytes is slow and undesirable. */
#define SLOW_BYTE_ACCESS 1
/* Don't perform CSE on function addresses. */
#define NO_FUNCTION_CSE
+/* This value is used in tree-sra to decide whether it might benefical
+ to split a struct move into several word-size moves. For S/390
+ only small values make sense here since struct moves are relatively
+ cheap thanks to mvc so the small default value choosen for archs
+ with memmove patterns should be ok. But this value is multiplied
+ in tree-sra with UNITS_PER_WORD to make a decision so we adjust it
+ here to compensate for that factor since mvc costs exactly the same
+ on 31 and 64 bit. */
+#define MOVE_RATIO(speed) (TARGET_64BIT? 2 : 4)
+
/* Sections. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
/* Machine-specific symbol_ref flags. */
-#define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
+#define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
+#define SYMBOL_REF_ALIGN1_P(X) \
+ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_ALIGN1))
+#define SYMBOL_FLAG_NOT_NATURALLY_ALIGNED (SYMBOL_FLAG_MACH_DEP << 1)
+#define SYMBOL_REF_NOT_NATURALLY_ALIGNED_P(X) \
+ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_NOT_NATURALLY_ALIGNED))
/* Check whether integer displacement is in range. */
#define DISP_IN_RANGE(d) \