From deac3726d786d71a31243f1348e467cb0251a522 Mon Sep 17 00:00:00 2001 From: rth Date: Wed, 2 Feb 2005 00:30:36 +0000 Subject: [PATCH] PR target/19680 * config/i386/i386.h (MODES_TIEABLE_P): Use ix86_modes_tieable_p. * config/i386/i386.c (ix86_hard_regno_mode_ok): Change return type to bool. (ix86_tieable_integer_mode_p, ix86_modes_tieable_p): New. * config/i386/i386-protos.h: Update. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94575 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 ++++++ gcc/config/i386/i386-protos.h | 3 +- gcc/config/i386/i386.c | 64 ++++++++++++++++++++++++++++++++++++++++++- gcc/config/i386/i386.h | 11 +------- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ac04aeb..6390a0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-02-01 Richard Henderson PR tree-optimization/19217 diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index feacd2d..53edfd1 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -180,7 +180,8 @@ extern rtx ix86_force_to_memory (enum machine_mode, rtx); extern void ix86_free_from_memory (enum machine_mode); extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, rtx, rtx, rtx, rtx); -extern int ix86_hard_regno_mode_ok (int, enum machine_mode); +extern bool ix86_hard_regno_mode_ok (int, enum machine_mode); +extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode); extern int ix86_register_move_cost (enum machine_mode, enum reg_class, enum reg_class); extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class, diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f72bd3d..bc680c8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -14997,7 +14997,8 @@ ix86_register_move_cost (enum machine_mode mode, enum reg_class class1, } /* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */ -int + +bool ix86_hard_regno_mode_ok (int regno, enum machine_mode mode) { /* Flags and only flags can only hold CCmode values. */ @@ -15038,6 +15039,67 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode) return reload_in_progress || reload_completed || !TARGET_PARTIAL_REG_STALL; } +/* A subroutine of ix86_modes_tieable_p. Return true if MODE is a + tieable integer mode. */ + +static bool +ix86_tieable_integer_mode_p (enum machine_mode mode) +{ + switch (mode) + { + case HImode: + case SImode: + return true; + + case QImode: + return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL; + + case DImode: + return TARGET_64BIT; + + default: + return false; + } +} + +/* Return true if MODE1 is accessible in a register that can hold MODE2 + without copying. That is, all register classes that can hold MODE2 + can also hold MODE1. */ + +bool +ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2) +{ + if (mode1 == mode2) + return true; + + if (ix86_tieable_integer_mode_p (mode1) + && ix86_tieable_integer_mode_p (mode2)) + return true; + + /* MODE2 being XFmode implies fp stack or general regs, which means we + can tie any smaller floating point modes to it. Note that we do not + tie this with TFmode. */ + if (mode2 == XFmode) + return mode1 == SFmode || mode1 == DFmode; + + /* MODE2 being DFmode implies fp stack, general or sse regs, which means + that we can tie it with SFmode. */ + if (mode2 == DFmode) + return mode1 == SFmode; + + /* If MODE2 is only appropriate for an SSE register, then tie with + any other mode acceptable to SSE registers. */ + if (SSE_REG_MODE_P (mode2)) + return ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1); + + /* If MODE2 is appropriate for an MMX (or SSE) register, then tie + with any other mode acceptable to MMX registers. */ + if (MMX_REG_MODE_P (mode2)) + return ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1); + + return false; +} + /* Return the cost of moving data of mode M between a register and memory. A value of 2 is the default; this cost is relative to those in `REGISTER_MOVE_COST'. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index e155a4f..5c2046a 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1122,16 +1122,7 @@ do { \ If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, for any hard reg, then this must be 0 for correct output. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - ((MODE1) == (MODE2) \ - || (((MODE1) == HImode || (MODE1) == SImode \ - || ((MODE1) == QImode \ - && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL)) \ - || ((MODE1) == DImode && TARGET_64BIT)) \ - && ((MODE2) == HImode || (MODE2) == SImode \ - || ((MODE2) == QImode \ - && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL)) \ - || ((MODE2) == DImode && TARGET_64BIT)))) +#define MODES_TIEABLE_P(MODE1, MODE2) ix86_modes_tieable_p (MODE1, MODE2) /* It is possible to write patterns to move flags; but until someone does it, */ -- 2.7.4