Commit f2f90c63 by Richard Henderson Committed by Richard Henderson

ia64-protos.h: Update.

	* config/ia64/ia64-protos.h: Update.
	* config/ia64/ia64.c (signed_inequality_operator): New.
	(ia64_expand_compare): New.
	(ia64_register_move_cost): Handle PR_REGS moves.
	(ia64_secondary_reload_class): Require a GR when moving to a PR.
	(struct reg_write_state): Add written_by_and/or.
	(struct reg_flags): Add is_and/or.
	(rws_update): Set them.
	(rws_access_regno): Test them to allow parallel comparisons.
	(rtx_needs_barrier): Recognize parallel comparisons.
	(emit_insn_group_barriers): Set prev_insn after a call stop bit.
	Call recog_memoized; ignore pred_rel_mutex.
	(emit_predicate_relation_info): Don't call find_basic_blocks here.
	(ia64_reorg): Do it here instead.
	* config/ia64/ia64.h: s/CCmode/BImode/g
	(MODES_TIEABLE_P): Don't tie BImode.
	(PREFERRED_RELOAD_CLASS): Do not reload operations into AR regs.
	(CONST_COSTS): Pick sensible values for CONST_INT based on context.
	(RTX_COSTS): Make multiply 4 insns.
	(MEMORY_MOVE_COST): New.
	(PREDICATE_CODES): Update.
	* config/ia64/ia64.md: s/CCmode/BImode/g
	(movcci, movbi): New.
	(andbi3, andcmbi3, iorbi3, iorcmbi3, one_cmplbi2): New.
	(cmpsi_and_0, cmpsi_and_1, cmpsi_andnot_0, cmpsi_andnot_1): New.
	(cmpdi_and_0, cmpdi_and_1, cmpdi_andnot_0, cmpdi_andnot_1): New.
	(tbit_and_0, tbit_and_1, tbit_and_2, tbit_and_3): New.
	(cmpsi_or_0, cmpsi_or_1, cmpsi_orcm_0, cmpsi_orcm_1): New.
	(cmpdi_or_0, cmpdi_or_1, cmpdi_orcm_0, cmpdi_orcm_1): New.
	(tbit_or_0, tbit_or_1, tbit_or_2, tbit_or_3): New.
	(mulsi, muldi): Use xmpy not xma.
	(cmpbi): New.
	(movcc, movcc_internal): Remove.
	(branch expanders): Use ia64_expand_compare.
	(setcc expanders): Likewise.
	(cmov insns): Use move_operand and ia64_move_ok.
	(pred_rel_mutex): Use unspec not unspec_volatile.  Prevent the
	scheduler from moving it past a use.
	* config/ia64/build.hacks: Remove.

From-SVN: r36510
parent 0d9f234d
2000-09-18 Richard Henderson <rth@cygnus.com>
* config/ia64/ia64-protos.h: Update.
* config/ia64/ia64.c (signed_inequality_operator): New.
(ia64_expand_compare): New.
(ia64_register_move_cost): Handle PR_REGS moves.
(ia64_secondary_reload_class): Require a GR when moving to a PR.
(struct reg_write_state): Add written_by_and/or.
(struct reg_flags): Add is_and/or.
(rws_update): Set them.
(rws_access_regno): Test them to allow parallel comparisons.
(rtx_needs_barrier): Recognize parallel comparisons.
(emit_insn_group_barriers): Set prev_insn after a call stop bit.
Call recog_memoized; ignore pred_rel_mutex.
(emit_predicate_relation_info): Don't call find_basic_blocks here.
(ia64_reorg): Do it here instead.
* config/ia64/ia64.h: s/CCmode/BImode/g
(MODES_TIEABLE_P): Don't tie BImode.
(PREFERRED_RELOAD_CLASS): Do not reload operations into AR regs.
(CONST_COSTS): Pick sensible values for CONST_INT based on context.
(RTX_COSTS): Make multiply 4 insns.
(MEMORY_MOVE_COST): New.
(PREDICATE_CODES): Update.
* config/ia64/ia64.md: s/CCmode/BImode/g
(movcci, movbi): New.
(andbi3, andcmbi3, iorbi3, iorcmbi3, one_cmplbi2): New.
(cmpsi_and_0, cmpsi_and_1, cmpsi_andnot_0, cmpsi_andnot_1): New.
(cmpdi_and_0, cmpdi_and_1, cmpdi_andnot_0, cmpdi_andnot_1): New.
(tbit_and_0, tbit_and_1, tbit_and_2, tbit_and_3): New.
(cmpsi_or_0, cmpsi_or_1, cmpsi_orcm_0, cmpsi_orcm_1): New.
(cmpdi_or_0, cmpdi_or_1, cmpdi_orcm_0, cmpdi_orcm_1): New.
(tbit_or_0, tbit_or_1, tbit_or_2, tbit_or_3): New.
(mulsi, muldi): Use xmpy not xma.
(cmpbi): New.
(movcc, movcc_internal): Remove.
(branch expanders): Use ia64_expand_compare.
(setcc expanders): Likewise.
(cmov insns): Use move_operand and ia64_move_ok.
(pred_rel_mutex): Use unspec not unspec_volatile. Prevent the
scheduler from moving it past a use.
* config/ia64/build.hacks: Remove.
Mon 18-Sep-2000 19:21:35 BST Neil Booth <NeilB@earthling.net>
* cpphash.h (HASHSTEP): Take character rather than pointer
......
The gcse.c patch fixes an optimization problem. This is probably not the right
solution, but it was quick. I will replace with a better solution later.
The libio/libstdc++ patches are useful if you have a version of glibc without
thread support. There is no official ia64 glibc version yet, and some of the
unofficial ones in common use are missing thread support. libio/libstdc++
assume that glibc always has thread support, so we need to patch them until
the official ia64 glibc is available.
Index: gcc/gcse.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/gcse.c,v
retrieving revision 1.87
diff -p -r1.87 gcse.c
*** gcse.c 2000/01/11 14:59:28 1.87
--- gcse.c 2000/02/16 04:17:06
*************** try_replace_reg (from, to, insn)
*** 4039,4045 ****
information. */
if (!success && !note)
{
! if (!set)
return 0;
note = REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
copy_rtx (SET_SRC (set)),
--- 4039,4048 ----
information. */
if (!success && !note)
{
! /* Don't add a REG_EQUAL note for a CCmode destination, because this
! confuses the code in cse.c that simplifies compare and branch
! instructions. */
! if (!set || GET_MODE_CLASS (GET_MODE (SET_DEST (set))) == MODE_CC)
return 0;
note = REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
copy_rtx (SET_SRC (set)),
Index: libio/configure.in
===================================================================
RCS file: /cvs/cvsfiles/devo/libio/configure.in,v
retrieving revision 1.57
diff -p -r1.57 configure.in
*** configure.in 1999/10/26 03:42:26 1.57
--- configure.in 2000/02/16 04:17:56
*************** case "${target}" in
*** 57,62 ****
--- 57,64 ----
frags="linux.mt linuxaxp1.mt mtsafe.mt" ;;
*-linux-gnulibc1)
frags=linuxlibc1.mt ;;
+ # ??? glibc does not have thread support yet, so we can't use mtsafe.mt.
+ ia64*-linux-gnu) frags="linux.mt" ;;
*-linux-gnu) frags="linux.mt mtsafe.mt" ;;
*-sco3.2v[45]*) frags=sco4.mt ;;
*-isc*) frags=isc.mt ;;
Index: libstdc++/configure.in
===================================================================
RCS file: /cvs/cvsfiles/devo/libstdc++/configure.in,v
retrieving revision 1.46
diff -p -r1.46 configure.in
*** configure.in 1999/09/21 19:26:16 1.46
--- configure.in 2000/02/16 04:17:57
*************** fi
*** 89,94 ****
--- 89,96 ----
case "${target}" in
alpha*-*-linux-gnulibc1) frags="${frags} linux.mt" ;;
powerpc*-*-linux-gnulibc1) frags="${frags} linux.mt" ;;
+ # ??? ia64 glibc port does not have thread support yet.
+ ia64*-*-linux-gnu) ;;
*-*-linux-gnu) frags="${frags} linux.mt" ;;
*-*-openbsd*)
case "x${enable_threads}" in
Index: libstdc++/stl/stl_config.h
===================================================================
RCS file: /cvs/cvsfiles/devo/libstdc++/stl/stl_config.h,v
retrieving revision 1.17
diff -p -r1.17 stl_config.h
*** stl_config.h 1999/12/24 16:21:31 1.17
--- stl_config.h 2000/02/16 04:17:58
***************
*** 168,174 ****
# if defined(__linux__)
/* glibc pre 2.0 is very buggy. We have to disable thread for it.
It should be upgraded to glibc 2.0 or later. */
! # if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS)
# define __STL_PTHREADS
# ifdef __STRICT_ANSI__
/* Work around a bug in the glibc 2.0.x pthread.h. */
--- 168,175 ----
# if defined(__linux__)
/* glibc pre 2.0 is very buggy. We have to disable thread for it.
It should be upgraded to glibc 2.0 or later. */
! /* ??? ia64 glibc port does not have thread support yet. */
! # if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS) && !defined(__ia64__)
# define __STL_PTHREADS
# ifdef __STRICT_ANSI__
/* Work around a bug in the glibc 2.0.x pthread.h. */
......@@ -56,6 +56,7 @@ extern int fetchadd_operand PARAMS((rtx, enum machine_mode));
extern int fr_reg_or_fp01_operand PARAMS((rtx, enum machine_mode));
extern int normal_comparison_operator PARAMS((rtx, enum machine_mode));
extern int adjusted_comparison_operator PARAMS((rtx, enum machine_mode));
extern int signed_inequality_operator PARAMS((rtx, enum machine_mode));
extern int call_multiple_values_operation PARAMS((rtx, enum machine_mode));
extern int destination_operand PARAMS((rtx, enum machine_mode));
extern int not_postinc_memory_operand PARAMS((rtx, enum machine_mode));
......@@ -71,6 +72,7 @@ extern int ia64_depz_field_mask PARAMS((rtx, rtx));
extern rtx ia64_gp_save_reg PARAMS((int));
extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
extern rtx spill_tfmode_operand PARAMS((rtx, int));
extern rtx ia64_expand_compare PARAMS((enum rtx_code, enum machine_mode));
extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
extern void ia64_expand_prologue PARAMS((void));
......
......@@ -813,13 +813,13 @@ while (0)
/* A C expression for the number of consecutive hard registers, starting at
register number REGNO, required to hold a value of mode MODE. */
/* ??? We say that CCmode values require two registers. This allows us to
/* ??? We say that BImode PR values require two registers. This allows us to
easily store the normal and inverted values. We use CCImode to indicate
a single predicate register. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
((REGNO) == PR_REG (0) && (MODE) == DImode ? 64 \
: PR_REGNO_P (REGNO) && (MODE) == CCmode ? 2 \
: PR_REGNO_P (REGNO) && (MODE) == BImode ? 2 \
: PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1 \
: FR_REGNO_P (REGNO) && (MODE) == TFmode ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
......@@ -828,12 +828,14 @@ while (0)
MODE in hard register number REGNO (or in several registers starting with
that one). */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
(FR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) != MODE_CC && (MODE) != TImode \
: PR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
: GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != TFmode \
: AR_REGNO_P (REGNO) ? (MODE) == DImode \
: BR_REGNO_P (REGNO) ? (MODE) == DImode \
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
(FR_REGNO_P (REGNO) ? \
GET_MODE_CLASS (MODE) != MODE_CC && (MODE) != TImode && (MODE) != BImode \
: PR_REGNO_P (REGNO) ? \
(MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC \
: GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != TFmode \
: AR_REGNO_P (REGNO) ? (MODE) == DImode \
: BR_REGNO_P (REGNO) ? (MODE) == DImode \
: 0)
/* A C expression that is nonzero if it is desirable to choose register
......@@ -843,22 +845,13 @@ while (0)
If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
zero. */
/* ??? If the comments are true, then this must be zero if one mode is CCmode,
INTEGRAL_MODE_P or FLOAT_MODE_P and the other is not. Otherwise, it is
true. */
/* Don't tie integer and FP modes, as that causes us to get integer registers
allocated for FP instructions. TFmode only supported in FP registers so
we can't tie it with any other modes. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
((GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) \
&& (((MODE1) == TFmode) == ((MODE2) == TFmode)))
/* Define this macro if the compiler should avoid copies to/from CCmode
registers. You should only define this macro if support fo copying to/from
CCmode is incomplete. */
/* ??? CCmode copies are very expensive, so we might want this defined. */
/* #define AVOID_CCMODE_COPIES */
#define MODES_TIEABLE_P(MODE1, MODE2) \
(GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \
&& (((MODE1) == TFmode) == ((MODE2) == TFmode)) \
&& (((MODE1) == BImode) == ((MODE2) == BImode)))
/* Handling Leaf Functions */
......@@ -910,9 +903,8 @@ enum reg_class
/* An initializer containing the names of the register classes as C string
constants. These names are used in writing some of the debugging dumps. */
#define REG_CLASS_NAMES \
{ "NO_REGS", "PR_REGS", "BR_REGS", "ADDL_REGS", "GR_REGS", \
"FR_REGS", "GR_AND_FR_REGS", "AR_M_REGS", "AR_I_REGS", \
"ALL_REGS" }
{ "NO_REGS", "PR_REGS", "BR_REGS", "ADDL_REGS", "GR_REGS", "FR_REGS", \
"GR_AND_FR_REGS", "AR_M_REGS", "AR_I_REGS", "ALL_REGS" }
/* An initializer containing the contents of the register classes, as integers
which are bit masks. The Nth integer specifies the contents of class N.
......@@ -1022,11 +1014,13 @@ enum reg_class
/* Don't allow volatile mem reloads into floating point registers. This
is defined to force reload to choose the r/m case instead of the f/f case
when reloading (set (reg fX) (mem/v)). */
when reloading (set (reg fX) (mem/v)).
Do not reload expressions into AR regs. */
#define PREFERRED_RELOAD_CLASS(X, CLASS) \
((CLASS == FR_REGS && GET_CODE (X) == MEM && MEM_VOLATILE_P (X)) \
? NO_REGS \
(CLASS == FR_REGS && GET_CODE (X) == MEM && MEM_VOLATILE_P (X) ? NO_REGS \
: GET_RTX_CLASS (GET_CODE (X)) != 'o' && CLASS > GR_AND_FR_REGS ? NO_REGS \
: CLASS)
/* You should define this macro to indicate to the reload phase that it may
......@@ -1061,7 +1055,7 @@ enum reg_class
This is closely related to the macro `HARD_REGNO_NREGS'. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
((MODE) == CCmode && (CLASS) == PR_REGS ? 2 \
((MODE) == BImode && (CLASS) == PR_REGS ? 2 \
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
......@@ -1823,29 +1817,49 @@ do { \
/* ??? This is incomplete. */
#define CONST_COSTS(X, CODE, OUTER_CODE) \
#define CONST_COSTS(X, CODE, OUTER_CODE) \
case CONST_INT: \
if ((X) == const0_rtx) \
return 0; \
switch (OUTER_CODE) \
{ \
case SET: \
return CONST_OK_FOR_J (INTVAL (X)) ? 0 : COSTS_N_INSNS (1); \
case PLUS: \
if (CONST_OK_FOR_I (INTVAL (X))) \
return 0; \
if (CONST_OK_FOR_J (INTVAL (X))) \
return 1; \
return COSTS_N_INSNS (1); \
default: \
if (CONST_OK_FOR_K (INTVAL (X)) || CONST_OK_FOR_L (INTVAL (X))) \
return 0; \
return COSTS_N_INSNS (1); \
} \
case CONST_DOUBLE: \
return COSTS_N_INSNS (1); \
case CONST: \
case SYMBOL_REF: \
case LABEL_REF: \
return COSTS_N_INSNS (1);
return COSTS_N_INSNS (2);
/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. */
/* ??? Should define this to get better optimized code. */
/* We make divide expensive, so that divide-by-constant will be optimized to
a multiply. */
#define RTX_COSTS(X, CODE, OUTER_CODE) \
#define RTX_COSTS(X, CODE, OUTER_CODE) \
case MULT: \
/* For multiplies wider than HImode, we have to go to the FPU, \
which normally involves copies. Plus there's the latency \
of the multiply itself. */ \
if (GET_MODE_SIZE (GET_MODE (X)) > 2) \
return COSTS_N_INSNS (4); \
return COSTS_N_INSNS (1); \
case DIV: \
case UDIV: \
case MOD: \
case UMOD: \
return COSTS_N_INSNS (20);
/* We make divide expensive, so that divide-by-constant will be \
optimized to a multiply. */ \
return COSTS_N_INSNS (60);
/* An expression giving the cost of an addressing mode that contains ADDRESS.
If not defined, the cost is computed from the ADDRESS expression and the
......@@ -1859,10 +1873,10 @@ do { \
#define REGISTER_MOVE_COST(FROM, TO) \
ia64_register_move_cost((FROM), (TO))
/* A C expression for the cost of moving data of mode M between a register and
memory. */
/* ??? Investigate. Might get better code by defining this. */
/* #define MEMORY_MOVE_COST(M,C,I) */
/* A C expression for the cost of moving data of mode M between a
register and memory. */
#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
((CLASS) == GENERAL_REGS || (CLASS) == FR_REGS ? 4 : 10)
/* A C expression for the cost of a branch instruction. A value of 1 is the
default; other values are interpreted relative to that. Used by the
......@@ -2682,6 +2696,7 @@ do { \
{ "fr_reg_or_fp01_operand", {SUBREG, REG, CONST_DOUBLE}}, \
{ "normal_comparison_operator", {EQ, NE, GT, LE, GTU, LEU}}, \
{ "adjusted_comparison_operator", {LT, GE, LTU, GEU}}, \
{ "signed_inequality_operator", {GE, GT, LE, LT}}, \
{ "call_multiple_values_operation", {PARALLEL}}, \
{ "predicate_operator", {NE, EQ}}, \
{ "ar_lc_reg_operand", {REG}}, \
......
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