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
This commit is contained in:
Andreas Krebbel 2010-04-13 09:04:31 +00:00 committed by Andreas Krebbel
parent 3b12359519
commit 9602b6a1b8
6 changed files with 534 additions and 245 deletions

View File

@ -1,3 +1,46 @@
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.

View File

@ -324,7 +324,7 @@ struct GTY(()) machine_function
#define cfun_frame_layout (cfun->machine->frame_layout)
#define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_LONG)
#define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
(1 << (BITNUM)))
#define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
@ -365,14 +365,25 @@ s390_libgcc_shift_count_mode (void)
return TARGET_64BIT ? DImode : SImode;
}
static enum machine_mode
s390_unwind_word_mode (void)
{
return TARGET_64BIT ? DImode : SImode;
}
/* Return true if the back end supports mode MODE. */
static bool
s390_scalar_mode_supported_p (enum machine_mode mode)
{
/* In contrast to the default implementation reject TImode constants on 31bit
TARGET_ZARCH for ABI compliance. */
if (!TARGET_64BIT && TARGET_ZARCH && mode == TImode)
return false;
if (DECIMAL_FLOAT_MODE_P (mode))
return default_decimal_float_supported_p ();
else
return default_scalar_mode_supported_p (mode);
return default_scalar_mode_supported_p (mode);
}
/* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
@ -2407,7 +2418,7 @@ s390_rtx_costs (rtx x, int code, int outer_code, int *total,
{
rtx left = XEXP (x, 0);
rtx right = XEXP (x, 1);
if (TARGET_64BIT)
if (TARGET_ZARCH)
{
if (GET_CODE (right) == CONST_INT
&& CONST_OK_FOR_K (INTVAL (right)))
@ -2468,7 +2479,7 @@ s390_rtx_costs (rtx x, int code, int outer_code, int *total,
{
rtx right = XEXP (x, 1);
if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
if (TARGET_64BIT)
if (TARGET_ZARCH)
*total = s390_cost->dsgfr;
else
*total = s390_cost->dr;
@ -2960,7 +2971,7 @@ s390_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
if (MEM_P (x)
&& s390_symref_operand_p (XEXP (x, 0), NULL, NULL)
&& (mode == QImode || mode == TImode || FLOAT_MODE_P (mode)
|| (!TARGET_64BIT && mode == DImode)
|| (!TARGET_ZARCH && mode == DImode)
|| ((mode == HImode || mode == SImode || mode == DImode)
&& (!s390_check_symref_alignment (XEXP (x, 0),
GET_MODE_SIZE (mode))))))
@ -4033,7 +4044,7 @@ s390_expand_setmem (rtx dst, rtx len, rtx val)
else
{
rtx dst_addr, src_addr, count, blocks, temp, dstp1 = NULL_RTX;
rtx dst_addr, count, blocks, temp, dstp1 = NULL_RTX;
rtx loop_start_label = gen_label_rtx ();
rtx loop_end_label = gen_label_rtx ();
rtx end_label = gen_label_rtx ();
@ -4044,7 +4055,6 @@ s390_expand_setmem (rtx dst, rtx len, rtx val)
mode = Pmode;
dst_addr = gen_reg_rtx (Pmode);
src_addr = gen_reg_rtx (Pmode);
count = gen_reg_rtx (mode);
blocks = gen_reg_rtx (mode);
@ -5412,7 +5422,6 @@ s390_first_cycle_multipass_dfa_lookahead (void)
return 4;
}
/* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
Fix up MEMs as required. */
@ -6810,9 +6819,9 @@ s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
}
if (TARGET_PACKED_STACK)
offset = -2 * UNITS_PER_WORD;
offset = -2 * UNITS_PER_LONG;
else
offset = RETURN_REGNUM * UNITS_PER_WORD;
offset = RETURN_REGNUM * UNITS_PER_LONG;
addr = plus_constant (frame, offset);
addr = memory_address (Pmode, addr);
@ -6831,7 +6840,7 @@ s390_back_chain_rtx (void)
if (TARGET_PACKED_STACK)
chain = plus_constant (stack_pointer_rtx,
STACK_POINTER_OFFSET - UNITS_PER_WORD);
STACK_POINTER_OFFSET - UNITS_PER_LONG);
else
chain = stack_pointer_rtx;
@ -6956,9 +6965,9 @@ s390_frame_area (int *area_bottom, int *area_top)
if (cfun_frame_layout.first_restore_gpr != -1)
{
b = (cfun_frame_layout.gprs_offset
+ cfun_frame_layout.first_restore_gpr * UNITS_PER_WORD);
+ cfun_frame_layout.first_restore_gpr * UNITS_PER_LONG);
t = b + (cfun_frame_layout.last_restore_gpr
- cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_WORD;
- cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_LONG;
}
if (TARGET_64BIT && cfun_save_high_fprs_p)
@ -7153,20 +7162,20 @@ s390_frame_info (void)
if (!TARGET_PACKED_STACK)
{
cfun_frame_layout.backchain_offset = 0;
cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
cfun_frame_layout.f0_offset = 16 * UNITS_PER_LONG;
cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
* UNITS_PER_WORD);
* UNITS_PER_LONG);
}
else if (TARGET_BACKCHAIN) /* kernel stack layout */
{
cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
- UNITS_PER_WORD);
- UNITS_PER_LONG);
cfun_frame_layout.gprs_offset
= (cfun_frame_layout.backchain_offset
- (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
* UNITS_PER_WORD);
* UNITS_PER_LONG);
if (TARGET_64BIT)
{
@ -7221,7 +7230,7 @@ s390_frame_info (void)
else
{
if (TARGET_BACKCHAIN)
cfun_frame_layout.frame_size += UNITS_PER_WORD;
cfun_frame_layout.frame_size += UNITS_PER_LONG;
/* No alignment trouble here because f8-f15 are only saved under
64 bit. */
@ -7340,7 +7349,7 @@ s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
case GENERAL_REGS:
if (REGNO_PAIR_OK (regno, mode))
{
if (TARGET_64BIT
if (TARGET_ZARCH
|| (mode != TFmode && mode != TCmode && mode != TDmode))
return true;
}
@ -7471,7 +7480,7 @@ s390_initial_elimination_offset (int from, int to)
index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot;
gcc_assert (index >= 0);
offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
offset += index * UNITS_PER_WORD;
offset += index * UNITS_PER_LONG;
break;
case BASE_REGNUM:
@ -7607,7 +7616,7 @@ save_gprs (rtx base, int offset, int first, int last)
if (start > last)
return insn;
addr = plus_constant (base, offset + (start - first) * UNITS_PER_WORD);
addr = plus_constant (base, offset + (start - first) * UNITS_PER_LONG);
note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
gen_rtx_REG (Pmode, start),
GEN_INT (last - start + 1));
@ -7756,7 +7765,7 @@ s390_emit_prologue (void)
{
insn = save_gprs (stack_pointer_rtx,
cfun_frame_layout.gprs_offset +
UNITS_PER_WORD * (cfun_frame_layout.first_save_gpr
UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
- cfun_frame_layout.first_save_gpr_slot),
cfun_frame_layout.first_save_gpr,
cfun_frame_layout.last_save_gpr);
@ -8153,7 +8162,7 @@ s390_emit_epilogue (bool sibcall)
addr = plus_constant (frame_pointer,
offset + cfun_frame_layout.gprs_offset
+ (i - cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD);
* UNITS_PER_LONG);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, get_frame_alias_set ());
emit_move_insn (addr, gen_rtx_REG (Pmode, i));
@ -8182,7 +8191,7 @@ s390_emit_epilogue (bool sibcall)
offset + cfun_frame_layout.gprs_offset
+ (RETURN_REGNUM
- cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD);
* UNITS_PER_LONG);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, get_frame_alias_set ());
emit_move_insn (return_reg, addr);
@ -8193,7 +8202,7 @@ s390_emit_epilogue (bool sibcall)
offset + cfun_frame_layout.gprs_offset
+ (cfun_frame_layout.first_restore_gpr
- cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD,
* UNITS_PER_LONG,
cfun_frame_layout.first_restore_gpr,
cfun_frame_layout.last_restore_gpr);
insn = emit_insn (insn);
@ -8357,7 +8366,7 @@ s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
else if (s390_function_arg_integer (mode, type))
{
int size = s390_function_arg_size (mode, type);
cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
cum->gprs += ((size + UNITS_PER_LONG - 1) / UNITS_PER_LONG);
}
else
gcc_unreachable ();
@ -8396,12 +8405,25 @@ s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
else if (s390_function_arg_integer (mode, type))
{
int size = s390_function_arg_size (mode, type);
int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
int n_gprs = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
return 0;
else
else if (n_gprs == 1 || UNITS_PER_WORD == UNITS_PER_LONG)
return gen_rtx_REG (mode, cum->gprs + 2);
else if (n_gprs == 2)
{
rtvec p = rtvec_alloc (2);
RTVEC_ELT (p, 0)
= gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 2),
const0_rtx);
RTVEC_ELT (p, 1)
= gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 3),
GEN_INT (4));
return gen_rtx_PARALLEL (mode, p);
}
}
/* After the real arguments, expand_call calls us once again
@ -8451,7 +8473,7 @@ s390_promote_function_mode (const_tree type, enum machine_mode mode,
int for_return ATTRIBUTE_UNUSED)
{
if (INTEGRAL_MODE_P (mode)
&& GET_MODE_SIZE (mode) < UNITS_PER_WORD)
&& GET_MODE_SIZE (mode) < UNITS_PER_LONG)
{
if (POINTER_TYPE_P (type))
*punsignedp = POINTERS_EXTEND_UNSIGNED;
@ -8479,8 +8501,22 @@ s390_function_value (const_tree type, const_tree fn, enum machine_mode mode)
if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
return gen_rtx_REG (mode, 16);
else
else if (GET_MODE_SIZE (mode) <= UNITS_PER_LONG
|| UNITS_PER_LONG == UNITS_PER_WORD)
return gen_rtx_REG (mode, 2);
else if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_LONG)
{
rtvec p = rtvec_alloc (2);
RTVEC_ELT (p, 0)
= gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 2), const0_rtx);
RTVEC_ELT (p, 1)
= gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 3), GEN_INT (4));
return gen_rtx_PARALLEL (mode, p);
}
gcc_unreachable ();
}
@ -8628,7 +8664,7 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
size_int (-RETURN_REGNUM * UNITS_PER_WORD));
size_int (-RETURN_REGNUM * UNITS_PER_LONG));
t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
TREE_SIDE_EFFECTS (t) = 1;
@ -8702,9 +8738,9 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
/* kernel stack layout on 31 bit: It is assumed here that no padding
will be added by s390_frame_info because for va_args always an even
number of gprs has to be saved r15-r2 = 14 regs. */
sav_ofs = 2 * UNITS_PER_WORD;
sav_scale = UNITS_PER_WORD;
size = UNITS_PER_WORD;
sav_ofs = 2 * UNITS_PER_LONG;
sav_scale = UNITS_PER_LONG;
size = UNITS_PER_LONG;
max_reg = GP_ARG_NUM_REG - n_reg;
}
else if (s390_function_arg_float (TYPE_MODE (type), type))
@ -8719,7 +8755,7 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
indirect_p = 0;
reg = fpr;
n_reg = 1;
sav_ofs = 16 * UNITS_PER_WORD;
sav_ofs = 16 * UNITS_PER_LONG;
sav_scale = 8;
max_reg = FP_ARG_NUM_REG - n_reg;
}
@ -8734,17 +8770,17 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
/* Otherwise into GP registers. */
indirect_p = 0;
reg = gpr;
n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
n_reg = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
/* kernel stack layout on 31 bit: It is assumed here that no padding
will be added by s390_frame_info because for va_args always an even
number of gprs has to be saved r15-r2 = 14 regs. */
sav_ofs = 2 * UNITS_PER_WORD;
sav_ofs = 2 * UNITS_PER_LONG;
if (size < UNITS_PER_WORD)
sav_ofs += UNITS_PER_WORD - size;
if (size < UNITS_PER_LONG)
sav_ofs += UNITS_PER_LONG - size;
sav_scale = UNITS_PER_WORD;
sav_scale = UNITS_PER_LONG;
max_reg = GP_ARG_NUM_REG - n_reg;
}
@ -8776,9 +8812,9 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
/* ... Otherwise out of the overflow area. */
t = ovf;
if (size < UNITS_PER_WORD)
if (size < UNITS_PER_LONG)
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
size_int (UNITS_PER_WORD - size));
size_int (UNITS_PER_LONG - size));
gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
@ -9002,7 +9038,7 @@ s390_function_profiler (FILE *file, int labelno)
op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_LONG));
op[2] = gen_rtx_REG (Pmode, 1);
op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
@ -9408,14 +9444,50 @@ s390_call_saved_register_used (tree call_expr)
s390_function_arg_advance (&cum, mode, type, 0);
if (parm_rtx && REG_P (parm_rtx))
{
for (reg = 0;
reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
reg++)
if (! call_used_regs[reg + REGNO (parm_rtx)])
return true;
if (!parm_rtx)
continue;
if (REG_P (parm_rtx))
{
int n_regs;
/* Only integer registers (r6) are call saved and used for
parameter passing. */
if (REGNO_REG_CLASS (REGNO (parm_rtx)) == FP_REGS)
continue;
n_regs = ((GET_MODE_SIZE (GET_MODE (parm_rtx)) + UNITS_PER_LONG - 1)
/ UNITS_PER_LONG);
for (reg = 0; reg < n_regs; reg++)
if (!call_used_regs[reg + REGNO (parm_rtx)])
return true;
}
if (GET_CODE (parm_rtx) == PARALLEL)
{
int i;
for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
{
rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
int n_regs;
gcc_assert (REG_P (r));
/* Only integer registers (r6) are call saved and used
for parameter passing. */
if (REGNO_REG_CLASS (REGNO (r)) == FP_REGS)
continue;
n_regs = ((GET_MODE_SIZE (GET_MODE (r)) + UNITS_PER_LONG - 1)
/ UNITS_PER_LONG);
for (reg = 0; reg < n_regs; reg++)
if (!call_used_regs[reg + REGNO (r)])
return true;
}
}
}
return false;
}
@ -9661,7 +9733,7 @@ s390_optimize_prologue (void)
{
new_insn = save_gprs (base,
off + (cfun_frame_layout.first_save_gpr
- first) * UNITS_PER_WORD,
- first) * UNITS_PER_LONG,
cfun_frame_layout.first_save_gpr,
cfun_frame_layout.last_save_gpr);
new_insn = emit_insn_before (new_insn, insn);
@ -9722,7 +9794,7 @@ s390_optimize_prologue (void)
{
new_insn = restore_gprs (base,
off + (cfun_frame_layout.first_restore_gpr
- first) * UNITS_PER_WORD,
- first) * UNITS_PER_LONG,
cfun_frame_layout.first_restore_gpr,
cfun_frame_layout.last_restore_gpr);
new_insn = emit_insn_before (new_insn, insn);
@ -10319,12 +10391,16 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION s390_handle_option
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true
@ -10438,6 +10514,9 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT s390_trampoline_init
#undef TARGET_UNWIND_WORD_MODE
#define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h"

View File

@ -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)); \

File diff suppressed because it is too large Load Diff

View 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

View File

@ -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