Commit 9602b6a1 by Andreas Krebbel Committed by Andreas Krebbel

s390.md: Replace TARGET_64BIT with TARGET_ZARCH.

2010-04-13  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
            Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
	
	* gcc/config/s390/s390.md: Replace TARGET_64BIT with TARGET_ZARCH.
	* gcc/config/s390/s390.c: Replace UNTIS_PER_WORD with
	UNITS_PER_LONG where it is ABI relevant.	
	(s390_return_addr_rtx): Likewise.
	(s390_back_chain_rtx): Likewise.
	(s390_frame_area): Likewise.
	(s390_frame_info): Likewise.
	(s390_initial_elimination_offset): Likewise.
	(save_gprs): Likewise.
	(s390_emit_prologue): Likewise.
	(s390_emit_epilogue): Likewise.
	(s390_function_arg_advance): Likewise.
	(s390_function_arg): Likewise.
	(s390_va_start): Likewise.
	(s390_gimplify_va_arg): Likewise.
	(s390_function_profiler): Likewise.
	(s390_optimize_prologue): Likewise.
	(s390_rtx_costs): Likewise.
	(s390_secondary_reload): Likewise.
	(s390_promote_function_mode): Likewise.
	(s390_hard_regno_mode_ok): Replace TARGET_64BIT with TARGET_ZARCH.
	(s390_scalar_mode_supported_p): Disallow TImode if no 64 bit
	registers available.
	(s390_unwind_word_mode): New function.
	(s390_function_value): Split 64 bit values into register pair if
	used as return value.
	(s390_call_saved_register_used): Don't use HARD_REGNO_NREGS for
	function call parameters.  Handle parallels.
	(TARGET_SCALAR_MODE_SUPPORTED_P): New macro.
	(HARD_REGNO_CALL_PART_CLOBBERED): New macro.
	(DWARF_CIE_DATA_ALIGNMENT): New macro.
	(s390_expand_setmem): Remove unused variable src_addr.
	* gcc/longlong.h: Make smul_ppmm and sdiv_qrnnd inline asms to
	deal with 64 bit registers.	
	* gcc/config/s390/s390.h: Define __zarch__ predefined macro.
	Replace UNITS_PER_WORD with UNITS_PER_LONG where it is ABI relevant.
	(UNITS_PER_LONG): New macro.
	* libjava/include/s390-signal.h: Define extended ucontext
	structure containing the upper halfs of the 64 bit registers.


Co-Authored-By: Ulrich Weigand <uweigand@de.ibm.com>

From-SVN: r158257
parent 3b123595
2010-04-13 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gcc/config/s390/s390.md: Replace TARGET_64BIT with TARGET_ZARCH.
* gcc/config/s390/s390.c: Replace UNTIS_PER_WORD with
UNITS_PER_LONG where it is ABI relevant.
(s390_return_addr_rtx): Likewise.
(s390_back_chain_rtx): Likewise.
(s390_frame_area): Likewise.
(s390_frame_info): Likewise.
(s390_initial_elimination_offset): Likewise.
(save_gprs): Likewise.
(s390_emit_prologue): Likewise.
(s390_emit_epilogue): Likewise.
(s390_function_arg_advance): Likewise.
(s390_function_arg): Likewise.
(s390_va_start): Likewise.
(s390_gimplify_va_arg): Likewise.
(s390_function_profiler): Likewise.
(s390_optimize_prologue): Likewise.
(s390_rtx_costs): Likewise.
(s390_secondary_reload): Likewise.
(s390_promote_function_mode): Likewise.
(s390_hard_regno_mode_ok): Replace TARGET_64BIT with TARGET_ZARCH.
(s390_scalar_mode_supported_p): Disallow TImode if no 64 bit
registers available.
(s390_unwind_word_mode): New function.
(s390_function_value): Split 64 bit values into register pair if
used as return value.
(s390_call_saved_register_used): Don't use HARD_REGNO_NREGS for
function call parameters. Handle parallels.
(TARGET_SCALAR_MODE_SUPPORTED_P): New macro.
(HARD_REGNO_CALL_PART_CLOBBERED): New macro.
(DWARF_CIE_DATA_ALIGNMENT): New macro.
(s390_expand_setmem): Remove unused variable src_addr.
* gcc/longlong.h: Make smul_ppmm and sdiv_qrnnd inline asms to
deal with 64 bit registers.
* gcc/config/s390/s390.h: Define __zarch__ predefined macro.
Replace UNITS_PER_WORD with UNITS_PER_LONG where it is ABI relevant.
(UNITS_PER_LONG): New macro.
* libjava/include/s390-signal.h: Define extended ucontext
structure containing the upper halfs of the 64 bit registers.
2010-04-13 Simon Baldwin <simonb@google.com>
* cfgexpand.c (gimple_expand_cfg): Clarify warning message text.
......
......@@ -108,6 +108,8 @@ extern int s390_arch_flags;
builtin_assert ("cpu=s390"); \
builtin_assert ("machine=s390"); \
builtin_define ("__s390__"); \
if (TARGET_ZARCH) \
builtin_define ("__zarch__"); \
if (TARGET_64BIT) \
builtin_define ("__s390x__"); \
if (TARGET_LONG_DOUBLE_128) \
......@@ -185,17 +187,6 @@ extern int s390_arch_flags;
#define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \
| S390_TDC_NEGATIVE_INFINITY )
/* In libgcc2, determine target settings as compile-time constants. */
#ifdef IN_LIBGCC2
#undef TARGET_64BIT
#ifdef __s390x__
#define TARGET_64BIT 1
#else
#define TARGET_64BIT 0
#endif
#endif
/* Target machine storage layout. */
/* Everything is big-endian. */
......@@ -203,12 +194,33 @@ extern int s390_arch_flags;
#define BYTES_BIG_ENDIAN 1
#define WORDS_BIG_ENDIAN 1
/* Width of a word, in units (bytes). */
#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
#define STACK_SIZE_MODE (Pmode)
#ifndef IN_LIBGCC2
#define MIN_UNITS_PER_WORD 4
/* Width of a word, in units (bytes). */
#define UNITS_PER_WORD (TARGET_ZARCH ? 8 : 4)
/* Width of a pointer. To be used instead of UNITS_PER_WORD in
ABI-relevant contexts. This always matches
GET_MODE_SIZE (Pmode). */
#define UNITS_PER_LONG (TARGET_64BIT ? 8 : 4)
#define MIN_UNITS_PER_WORD 4
#define MAX_BITS_PER_WORD 64
#else
/* In libgcc, UNITS_PER_WORD has ABI-relevant effects, e.g. whether
the library should export TImode functions or not. Thus, we have
to redefine UNITS_PER_WORD depending on __s390x__ for libgcc. */
#ifdef __s390x__
#define UNITS_PER_WORD 8
#else
#define UNITS_PER_WORD 4
#endif
#endif
#define MAX_BITS_PER_WORD 64
/* Width of a pointer, in bits. */
#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32)
......@@ -402,6 +414,15 @@ extern int s390_arch_flags;
(((MODE1) == SFmode || (MODE1) == DFmode) \
== ((MODE2) == SFmode || (MODE2) == DFmode))
/* When generating code that runs in z/Architecture mode,
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))
/* Maximum number of registers to represent a value of mode MODE
in a register of class CLASS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
......@@ -573,7 +594,7 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
the corresponding RETURN_REGNUM register was saved. */
#define DYNAMIC_CHAIN_ADDRESS(FRAME) \
(TARGET_PACKED_STACK ? \
plus_constant ((FRAME), STACK_POINTER_OFFSET - UNITS_PER_WORD) : (FRAME))
plus_constant ((FRAME), STACK_POINTER_OFFSET - UNITS_PER_LONG) : (FRAME))
/* For -mpacked-stack this adds 160 - 8 (96 - 4) to the output of
builtin_frame_address. Otherwise arg pointer -
......@@ -609,6 +630,9 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4 \
: DW_EH_PE_absptr)
/* Register save slot alignment. */
#define DWARF_CIE_DATA_ALIGNMENT (-UNITS_PER_LONG)
/* Frame registers. */
......@@ -790,19 +814,19 @@ do { \
/* The maximum number of bytes that a single instruction can move quickly
between memory and registers or between two memory locations. */
#define MOVE_MAX (TARGET_64BIT ? 16 : 8)
#define MOVE_MAX_PIECES (TARGET_64BIT ? 8 : 4)
#define MOVE_MAX (TARGET_ZARCH ? 16 : 8)
#define MOVE_MAX_PIECES (TARGET_ZARCH ? 8 : 4)
#define MAX_MOVE_MAX 16
/* Determine whether to use move_by_pieces or block move insn. */
#define MOVE_BY_PIECES_P(SIZE, ALIGN) \
( (SIZE) == 1 || (SIZE) == 2 || (SIZE) == 4 \
|| (TARGET_64BIT && (SIZE) == 8) )
|| (TARGET_ZARCH && (SIZE) == 8) )
/* Determine whether to use clear_by_pieces or block clear insn. */
#define CLEAR_BY_PIECES_P(SIZE, ALIGN) \
( (SIZE) == 1 || (SIZE) == 2 || (SIZE) == 4 \
|| (TARGET_64BIT && (SIZE) == 8) )
|| (TARGET_ZARCH && (SIZE) == 8) )
/* This macro is used to determine whether store_by_pieces should be
called to "memcpy" storage when the source is a constant string. */
......@@ -907,7 +931,7 @@ do { \
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
do { \
char buf[32]; \
fputs (integer_asm_op (UNITS_PER_WORD, TRUE), (FILE)); \
fputs (integer_asm_op (UNITS_PER_LONG, TRUE), (FILE)); \
ASM_GENERATE_INTERNAL_LABEL (buf, "L", (VALUE)); \
assemble_name ((FILE), buf); \
fputc ('\n', (FILE)); \
......@@ -917,7 +941,7 @@ do { \
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
do { \
char buf[32]; \
fputs (integer_asm_op (UNITS_PER_WORD, TRUE), (FILE)); \
fputs (integer_asm_op (UNITS_PER_LONG, TRUE), (FILE)); \
ASM_GENERATE_INTERNAL_LABEL (buf, "L", (VALUE)); \
assemble_name ((FILE), buf); \
fputc ('-', (FILE)); \
......
......@@ -318,6 +318,7 @@ UDItype __umulsidi3 (USItype, USItype);
#endif
#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
#if !defined (__zarch__)
#define smul_ppmm(xh, xl, m0, m1) \
do { \
union {DItype __ll; \
......@@ -339,6 +340,28 @@ UDItype __umulsidi3 (USItype, USItype);
: "0" (__x.__ll), "r" (d)); \
(q) = __x.__i.__l; (r) = __x.__i.__h; \
} while (0)
#else
#define smul_ppmm(xh, xl, m0, m1) \
do { \
register SItype r0 __asm__ ("0"); \
register SItype r1 __asm__ ("1") = m0; \
\
__asm__ ("mr\t%%r0,%3" \
: "=r" (r0), "=r" (r1) \
: "r" (r1), "r" (m1)); \
(xh) = r1; (xl) = r0; \
} while (0)
#define sdiv_qrnnd(q, r, n1, n0, d) \
do { \
register SItype r0 __asm__ ("0") = n0; \
register SItype r1 __asm__ ("1") = n1; \
\
__asm__ ("dr\t%%r0,%3" \
: "=r" (r0), "=r" (r1) \
: "r" (r0), "r" (r1), "r" (d)); \
(q) = r0; (r) = r1; \
} while (0)
#endif /* __zarch__ */
#endif
#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
......
......@@ -39,6 +39,7 @@ static void _name (int, siginfo_t *_si __attribute__((unused)), \
and if dividend and divisor are as above, we simply return from the signal
handler. This causes execution to continue after the instruction.
Before returning, we the set result registers as expected. */
#define UC_EXTENDED 0x00000001
#define HANDLE_DIVIDE_OVERFLOW \
do \
......@@ -47,6 +48,15 @@ do \
__builtin_extract_return_addr (_si->si_addr); \
unsigned long *_regs = _uc->uc_mcontext.gregs; \
int _r1, _r2, _d2, _x2, _b2; \
struct \
{ \
unsigned long int uc_flags; \
struct ucontext *uc_link; \
stack_t uc_stack; \
mcontext_t uc_mcontext; \
unsigned long sigmask[2]; \
unsigned long ext_regs[16]; \
} *_uc_ext = (typeof(_uc_ext))_uc; \
\
/* First, a couple of helper routines to decode instructions. */ \
struct _decode \
......@@ -119,8 +129,16 @@ do \
{ \
return _d + (_x? _regs[_x] : 0) + (_b? _regs[_b] : 0); \
} \
}; \
\
static inline int is_long_long_min_p (unsigned long *_regs, \
unsigned long *_ext_regs, \
int _r) \
{ \
return ((long long)_regs[_r] \
| (long long)_ext_regs[_r] << 32) == \
LONG_LONG_MIN; \
} \
}; \
\
/* DR r1,r2 */ \
if (_decode::_is_rr (_eip, 0x1d, &_r1, &_r2) \
......@@ -175,8 +193,58 @@ do \
_regs[_r1] = 0; \
return; \
} \
\
} \
\
/* The extended ucontext contains the upper halfs of the 64bit \
registers in 31bit applications. */ \
if (_uc->uc_flags & 1 == 1) \
{ \
/* DSGR r1,r2 */ \
if (_decode::_is_rre (_eip, 0xb9, 0x0d, &_r1, &_r2) \
&& (int) _regs[_r2] == -1 \
&& (int) _uc_ext->ext_regs[_r2] == -1 \
&& _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
_r1 + 1)) \
{ \
_regs[_r1] = 0; \
_uc_ext->ext_regs[_r1] = 0; \
return; \
} \
\
/* DSGFR r1,r2 */ \
if (_decode::_is_rre (_eip, 0xb9, 0x1d, &_r1, &_r2) \
&& (int) _regs[_r2] == -1 \
&& _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
_r1 + 1)) \
{ \
_regs[_r1] = 0; \
_uc_ext->ext_regs[_r1] = 0; \
return; \
} \
\
/* DSG r1,d2(x2,b2) */ \
if (_decode::_is_rxy (_eip, 0xe3, 0x0d, &_r1, &_d2, &_x2, &_b2) \
&& *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1 \
&& *(int *) _decode::_eff (_regs, _d2 + 4, _x2, _b2) == -1 \
&& _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
_r1 + 1)) \
{ \
_regs[_r1] = 0; \
_uc_ext->ext_regs[_r1] = 0; \
return; \
} \
\
/* DSGF r1,d2(x2,b2) */ \
if (_decode::_is_rxy (_eip, 0xe3, 0x1d, &_r1, &_d2, &_x2, &_b2) \
&& *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1 \
&& _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
_r1 + 1)) \
{ \
_regs[_r1] = 0; \
_uc_ext->ext_regs[_r1] = 0; \
return; \
} \
} \
} \
while (0)
/* For an explanation why we cannot simply use sigaction to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment