Commit f314b9b1 by Ulrich Weigand Committed by Ulrich Weigand

Bring s390 backend back in sync with branch.

From-SVN: r44810
parent dddba205
2001-08-11 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.c (targetm): Define TARGET_ASM_OPEN_PAREN
and TARGET_ASM_CLOSE_PAREN.
(regclass_map): CC register belongs to class NO_REGS.
(legitimize_pic_address): Don't generate unnecessary moves
(to avoid confusing loop optimization).
(check_and_change_labels): Replace jump_long by indirect_jump.
(s390_final_chunkify): Don't start a new literal pool on section
switch in 64-bit code.
(s390_va_start, s390_va_arg): Fixed incorrect sizes for 64-bit.
* config/s390/s390.h (TARGET_SWITCHES): Renamed debug_arg to debug.
(MAX_BITS_PER_WORD, MAX_LONG_TYPE_SIZE): Set to 64 (for 64-bit).
(HARD_REGNO_MODE_OK, RETURN_IN_MEMORY): Support complex integer
modes correctly.
(reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Remove CC_REGS.
(EH_RETURN_HANDLER_RTX): Fixed incorrect offset for 64-bit.
(CONST_COSTS): Fixed incorrect costs.
* config/s390/s390.md (fixuns_trunc[sd]f[sd]i2, udivsi3, umodsi3):
Use emit_jump instead of emit_jump_insn (gen_jump).
(divsi3, modsi3): Clobber low word of divmoddisi3 before shifting
(to avoid confusing flow analysis).
(tablejump, tablejump1, tablejump2): Removed. Replaced by casesi.
(casesi, casesi_jump): New.
(jump_long): Removed. Functionality merged into indirect_jump.
(indirect_jump): Accept address_operand, not just register_operand.
(cjump_long, icjump_long): Use same logic as indirect_jump.
(builtin_setjmp_setup, builtin_setjmp_receiver, builtin_longjmp):
Fixed broken setjmp/longjmp handling.
(do_builtin_setjmp_setup): Removed.
* config/s390/linux.h (ASM_OUTPUT_DOUBLE_INT): Work around
broken GNU as versions that don't accept .quad with large
negative values. Use hexadecimal output instead.
(ASM_OUTPUT_ADDR_DIFF_ELT): Adapt to new casesi insn.
(ASM_OPEN_PAREN, ASM_CLOSE_PAREN, FUNCTION_PROLOGUE,
FUNCTION_EPILOGUE): Removed. Now in targetm.
* config/s390/linux64.h (CALL_USED_REGISTERS): Add CC register.
* config/s390/fixdfdi.h: Add missing copyright statement.
Fix type conflicts on 64-bit. Add missing SFmode routines.
* s390.c, s390.h, s390.md, linux.h, linux64.h: Fixed incorrect
email address.
2001-08-11 Richard Henderson <rth@redhat.com>
* rtl.h (REG_EH_RETHROW): Remove.
......
/* Definitions of target machine for GNU compiler, for IBM S/390
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifdef L_fixunsdfdi
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
#define EXCESSD 1022
......@@ -5,25 +27,30 @@
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1))
#define HIDDEND_LL ((long long)1 << 52)
#define HIDDEND_LL ((UDItype_x)1 << 52)
typedef int DItype_x __attribute__ ((mode (DI)));
typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
typedef int SItype_x __attribute__ ((mode (SI)));
typedef unsigned int USItype_x __attribute__ ((mode (SI)));
union double_long {
double d;
struct {
long upper;
unsigned long lower;
SItype_x upper;
USItype_x lower;
} l;
long long ll;
UDItype_x ll;
};
/* convert double to unsigned int */
unsigned long long
UDItype_x
__fixunsdfdi (double a1)
{
register union double_long dl1;
register int exp;
register long long l;
register UDItype_x l;
dl1.d = a1;
......@@ -71,24 +98,29 @@ __fixunsdfdi (double a1)
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1))
#define HIDDEND_LL ((long long)1 << 52)
#define HIDDEND_LL ((UDItype_x)1 << 52)
typedef int DItype_x __attribute__ ((mode (DI)));
typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
typedef int SItype_x __attribute__ ((mode (SI)));
typedef unsigned int USItype_x __attribute__ ((mode (SI)));
union double_long {
double d;
struct {
long upper;
unsigned long lower;
SItype_x upper;
USItype_x lower;
} l;
long long ll;
UDItype_x ll;
};
/* convert double to int */
long long
DItype_x
__fixdfdi (double a1)
{
register union double_long dl1;
register int exp;
register long long l;
register DItype_x l;
dl1.d = a1;
......@@ -132,3 +164,138 @@ __fixdfdi (double a1)
#endif
#undef L_fixdfdi
#ifdef L_fixunssfdi
#define EXP(fp) (((fp.l) >> 23) & 0xFF)
#define EXCESS 126
#define SIGNBIT 0x80000000
#define SIGN(fp) ((fp.l) & SIGNBIT)
#define HIDDEN (1 << 23)
#define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN)
#define FRAC(fp) ((fp.l) & 0x7FFFFF)
typedef int DItype_x __attribute__ ((mode (DI)));
typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
typedef int SItype_x __attribute__ ((mode (SI)));
typedef unsigned int USItype_x __attribute__ ((mode (SI)));
union float_long
{
float f;
USItype_x l;
};
/* convert float to unsigned int */
UDItype_x
__fixunssfdi (float a1)
{
register union float_long fl1;
register int exp;
register UDItype_x l;
fl1.f = a1;
/* +/- 0, denormalized, negativ */
if (!EXP (fl1) || SIGN(fl1))
return 0;
exp = EXP (fl1) - EXCESS - 24;
/* number < 1 */
if (exp < -24)
return 0;
/* NaN */
if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */
return 0x0ULL;
/* Number big number & + inf */
if (exp >= 41) {
return 0xFFFFFFFFFFFFFFFFULL;
}
l = MANT(fl1);
if (exp > 0)
l <<= exp;
else
l >>= -exp;
return l;
}
#define __fixunssfdi ___fixunssfdi
#endif
#undef L_fixunssfdi
#ifdef L_fixsfdi
#define EXP(fp) (((fp.l) >> 23) & 0xFF)
#define EXCESS 126
#define SIGNBIT 0x80000000
#define SIGN(fp) ((fp.l) & SIGNBIT)
#define HIDDEN (1 << 23)
#define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN)
#define FRAC(fp) ((fp.l) & 0x7FFFFF)
typedef int DItype_x __attribute__ ((mode (DI)));
typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
typedef int SItype_x __attribute__ ((mode (SI)));
typedef unsigned int USItype_x __attribute__ ((mode (SI)));
union float_long
{
float f;
USItype_x l;
};
/* convert double to int */
DItype_x
__fixsfdi (float a1)
{
register union float_long fl1;
register int exp;
register DItype_x l;
fl1.f = a1;
/* +/- 0, denormalized */
if (!EXP (fl1))
return 0;
exp = EXP (fl1) - EXCESS - 24;
/* number < 1 */
if (exp < -24)
return 0;
/* NaN */
if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */
return 0x8000000000000000ULL;
/* Number big number & +/- inf */
if (exp >= 40) {
l = (long long)1<<63;
if (!SIGN(fl1))
l--;
return l;
}
l = MANT(fl1);
if (exp > 0)
l <<= exp;
else
l >>= -exp;
return (SIGN (fl1) ? -l : l);
}
#define __fixsfdi ___fixsfdi
#endif
#undef L_fixsfdi
/* Definitions for Linux for S/390.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (weigand@de.ibm.com).
Ulrich Weigand (uweigand@de.ibm.com).
This file is part of GNU CC.
......@@ -139,9 +139,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_DOUBLE_INT(FILE, VALUE) \
do { fprintf (FILE, "%s\t", ASM_QUAD); \
output_addr_const (FILE,(VALUE)); \
putc ('\n',FILE); \
do { fprintf ((FILE), "%s\t", ASM_QUAD); \
/* Work around bug in some GNU as versions */ \
if (GET_CODE (VALUE) == CONST_INT && INTVAL (VALUE) < INT_MIN) \
fprintf ((FILE), HOST_WIDE_INT_PRINT_HEX, INTVAL (x)); \
else \
output_addr_const ((FILE), (VALUE)); \
putc ('\n', (FILE)); \
} while (0)
......@@ -180,22 +184,14 @@ do { fprintf (FILE, "%s\t", ASM_LONG); \
/* This is how to output an element of a case-vector that is absolute. */
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
fprintf (FILE, "%s %s%d\n", TARGET_64BIT?ASM_QUAD:ASM_LONG, \
fprintf (FILE, "%s\t%s%d\n", TARGET_64BIT?ASM_QUAD:ASM_LONG, \
LPREFIX, VALUE)
/* This is how to output an element of a case-vector that is relative. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
fprintf (FILE, "%s %s%d-.LT%X_%X\n" ,TARGET_64BIT?ASM_QUAD:ASM_LONG, \
LPREFIX, VALUE, s390_function_count,s390_pool_count)
/* Define the parentheses used to group arithmetic operations
in assembler code. */
#undef ASM_OPEN_PAREN
#undef ASM_CLOSE_PAREN
#define ASM_OPEN_PAREN ""
#define ASM_CLOSE_PAREN ""
fprintf (FILE, "%s\t%s%d-%s%d\n", TARGET_64BIT?ASM_QUAD:ASM_LONG, \
LPREFIX, VALUE, LPREFIX, REL)
......@@ -293,24 +289,6 @@ do { \
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
/*
* This macro generates the assembly code for function entry.
*/
#define FUNCTION_PROLOGUE(FILE, LSIZE) s390_function_prologue (FILE, LSIZE)
/* This macro generates the assembly code for function exit, on machines
that need it. If FUNCTION_EPILOGUE is not defined then individual
return instructions are generated for each return statement. Args are
same as for FUNCTION_PROLOGUE.
The function epilogue should not depend on the current stack pointer!
It should use the frame pointer only. This is mandatory because
of alloca; we also take advantage of it to omit stack adjustments
before returning. */
#define FUNCTION_EPILOGUE(FILE, LSIZE) s390_function_epilogue(FILE, LSIZE)
/* Select section for constant in constant pool.
We are in the right section.
undef for 64 bit mode (linux64.h).
......
/* Definitions for Linux for s/390 zSeries
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (weigand@de.ibm.com).
Ulrich Weigand (uweigand@de.ibm.com).
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
......@@ -77,6 +77,6 @@ Boston, MA 02111-1307, USA. */
1, 1, 1, 1, \
0, 0, 0, 0, \
0, 0, 0, 0, \
1 }
1, 1 }
#endif
/* Subroutines used for code generation on IBM S/390 and zSeries
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (weigand@de.ibm.com).
Ulrich Weigand (uweigand@de.ibm.com).
This file is part of GNU CC.
......@@ -53,6 +53,12 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE s390_function_epilogue
#undef TARGET_ASM_OPEN_PAREN
#define TARGET_ASM_OPEN_PAREN ""
#undef TARGET_ASM_CLOSE_PAREN
#define TARGET_ASM_CLOSE_PAREN ""
struct gcc_target targetm = TARGET_INITIALIZER;
extern int reload_completed;
......@@ -173,7 +179,7 @@ enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
ADDR_REGS, CC_REGS
ADDR_REGS, NO_REGS
};
......@@ -959,11 +965,6 @@ legitimize_pic_address (orig, reg)
case 112:
case 114:
new = force_const_mem (SImode, orig);
if (reg != 0)
{
emit_move_insn (reg, new);
new = reg;
}
break;
/* @GOTENT is OK as is. */
......@@ -1080,11 +1081,6 @@ legitimize_pic_address (orig, reg)
abort();
new = force_const_mem (SImode, orig);
if (reg != 0)
{
emit_move_insn (reg, new);
new = reg;
}
}
/* Otherwise, compute the sum. */
......@@ -1700,7 +1696,7 @@ check_and_change_labels (rtx insn, int *ltorg_uids)
}
emit_insn_before (gen_movsi (temp_reg, target), insn);
tmp = emit_jump_insn_before (gen_jump_long (jump), insn);
tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
remove_insn (insn);
INSN_ADDRESSES_NEW (tmp, -1);
return tmp;
......@@ -1736,7 +1732,7 @@ check_and_change_labels (rtx insn, int *ltorg_uids)
label1 = gen_label_rtx ();
emit_jump_insn_before (gen_icjump (label1, XEXP (body, 0)), insn);
emit_insn_before (gen_movsi (temp_reg, target), insn);
tmp = emit_jump_insn_before (gen_jump_long (jump), insn);
tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1);
remove_insn (insn);
return tmp;
......@@ -1770,7 +1766,7 @@ check_and_change_labels (rtx insn, int *ltorg_uids)
label1 = gen_label_rtx ();
emit_jump_insn_before (gen_cjump (label1, XEXP (body, 0)), insn);
emit_insn_before (gen_movsi (temp_reg, target), insn);
tmp = emit_jump_insn_before (gen_jump_long (jump), insn);
tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn);
INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1);
remove_insn (insn);
return tmp;
......@@ -1862,7 +1858,7 @@ s390_final_chunkify (int chunkify)
warning ("no code label found");
}
}
else if (GET_CODE (PATTERN (insn)) == ASM_INPUT)
else if (GET_CODE (PATTERN (insn)) == ASM_INPUT && !TARGET_64BIT)
{
asms = XSTR (PATTERN (insn),0);
......@@ -2732,7 +2728,7 @@ s390_va_start (int stdarg_p, tree valist, rtx nextarg)
off = INTVAL (current_function_arg_offset_rtx);
off = off < 0 ? 0 : off;
if (! stdarg_p)
off = off > 0 ? off - 4 : off;
off = off > 0 ? off - UNITS_PER_WORD : off;
if (TARGET_DEBUG_ARG)
fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
n_gpr, n_fpr, off);
......@@ -2809,7 +2805,7 @@ s390_va_arg (tree valist, tree type)
indirect_p = 1;
reg = gpr;
n_reg = 1;
sav_ofs = 8;
sav_ofs = 2 * UNITS_PER_WORD;
sav_scale = UNITS_PER_WORD;
size = UNITS_PER_WORD;
max_reg = 4;
......@@ -2826,7 +2822,7 @@ s390_va_arg (tree valist, tree type)
indirect_p = 0;
reg = fpr;
n_reg = 1;
sav_ofs = 16 * UNITS_PER_WORD;;
sav_ofs = 16 * UNITS_PER_WORD;
sav_scale = 8;
/* TARGET_64BIT has up to 4 parameter in fprs */
max_reg = TARGET_64BIT ? 3 : 1;
......
/* Definitions of target machine for GNU compiler, for IBM S/390
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (weigand@de.ibm.com).
Ulrich Weigand (uweigand@de.ibm.com).
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
......@@ -54,8 +54,8 @@ extern int target_flags;
{ "no-backchain", -2,N_("Don't set backchain (faster, but debug harder")}, \
{ "small-exec", 4,N_("Use bras for execucable < 64k")}, \
{ "no-small-exec",-4,N_("Don't use bras")}, \
{ "debug_arg", 8,N_("Additional debug prints")}, \
{ "no-debug_arg", -8,N_("Don't print additional debug prints")}, \
{ "debug", 8,N_("Additional debug prints")}, \
{ "no-debug", -8,N_("Don't print additional debug prints")}, \
{ "64", 16,N_("64 bit mode")}, \
{ "31", -16,N_("31 bit mode")}, \
{ "mvcle", 32,N_("mvcle use")}, \
......@@ -95,7 +95,7 @@ extern int current_function_outgoing_args_size;
/* Width in bits of a "word", which is the contents of a machine register. */
#define BITS_PER_WORD (TARGET_64BIT ? 64 : 32)
#define MAX_BITS_PER_WORD 32
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
......@@ -121,7 +121,7 @@ extern int current_function_outgoing_args_size;
target machine. If you don't define this, the default is one
word. */
#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
#define MAX_LONG_TYPE_SIZE 32
#define MAX_LONG_TYPE_SIZE 64
/* A C expression for the size in bits of the type `long long' on the
target machine. If you don't define this, the default is two
......@@ -330,8 +330,7 @@ do \
(GET_MODE_CLASS(MODE) == MODE_FLOAT || \
GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT) : \
INT_REGNO_P(REGNO)? \
(!((TARGET_64BIT && (MODE) == TImode) || \
(!TARGET_64BIT && (MODE) == DImode)) || ((REGNO) & 1) == 0 ) : \
(HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1)) : \
CC_REGNO_P(REGNO)? \
GET_MODE_CLASS (MODE) == MODE_CC : \
0)
......@@ -427,7 +426,7 @@ while (0)
enum reg_class
{
NO_REGS, ADDR_REGS, GENERAL_REGS,
FP_REGS, CC_REGS, ALL_REGS, LIM_REG_CLASSES
FP_REGS, ALL_REGS, LIM_REG_CLASSES
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
......@@ -435,7 +434,7 @@ enum reg_class
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
{ "NO_REGS","ADDR_REGS", "GENERAL_REGS", "FP_REGS", "CC_REGS", "ALL_REGS" }
{ "NO_REGS","ADDR_REGS", "GENERAL_REGS", "FP_REGS", "ALL_REGS" }
/* Define which registers fit in which classes. This is an initializer for
a vector of HARD_REG_SET of length N_REG_CLASSES.
......@@ -447,7 +446,6 @@ enum reg_class
{ 0x0000fffe, 0x00000001 }, /* ADDR_REGS */ \
{ 0x0000ffff, 0x00000001 }, /* GENERAL_REGS */ \
{ 0xffff0000, 0x00000000 }, /* FP_REGS */ \
{ 0x00000000, 0x00000002 }, /* CC_REGS */ \
{ 0xffffffff, 0x00000003 }, /* ALL_REGS */ \
}
......@@ -591,7 +589,8 @@ extern enum reg_class regclass_map[]; /* smalled class containing REGNO */
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 10)
#define EH_RETURN_HANDLER_RTX \
gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, -40))
gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \
TARGET_64BIT? -48 : -40))
/* Define this if pushing a word on the stack makes the stack pointer a
smaller address. */
......@@ -769,8 +768,8 @@ CUMULATIVE_ARGS;
#define RETURN_IN_MEMORY(type) \
(TYPE_MODE (type) == BLKmode || \
TYPE_MODE (type) == DCmode || \
TYPE_MODE (type) == SCmode)
GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_INT || \
GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT)
/* Mode of stack savearea.
FUNCTION is VOIDmode because calling convention maintains SP.
......@@ -1569,11 +1568,11 @@ do { \
if ((OUTER_CODE == PLUS) && \
((INTVAL (RTX) > 32767) || \
(INTVAL (RTX) < -32768))) \
return 3; \
return COSTS_N_INSNS (3); \
case LABEL_REF: \
case SYMBOL_REF: \
case CONST_DOUBLE: \
return 1; \
return 0; \
/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
......
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