i386.h (SSE_CLASS_P, [...]): New macros.
* i386.h (SSE_CLASS_P, MMX_CLASS_P, MAYBE_FLOAT_CLASS_P, MAYBE_SSE_CLASS_P, MAYBE_MMX_CLASS_P): New macros. (PREFERRED_RELOAD_CLASS, SECONDARY_MEMORY_NEEDED): Move offline. (REGISTER_MOVE_COST): Likewise. * i386-protos.h (ix86_secondary_memory_needed, ix86_preferred_reload_class, ix86_register_move_cost): Declare. * i386.c (ix86_secondary_memory_needed, ix86_preferred_reload_class, ix86_register_move_cost): New function. From-SVN: r39622
This commit is contained in:
parent
a946dd0074
commit
f84aa48ac1
3 changed files with 125 additions and 32 deletions
|
@ -1,3 +1,14 @@
|
|||
Tue Feb 13 11:37:06 CET 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* i386.h (SSE_CLASS_P, MMX_CLASS_P, MAYBE_FLOAT_CLASS_P,
|
||||
MAYBE_SSE_CLASS_P, MAYBE_MMX_CLASS_P): New macros.
|
||||
(PREFERRED_RELOAD_CLASS, SECONDARY_MEMORY_NEEDED): Move offline.
|
||||
(REGISTER_MOVE_COST): Likewise.
|
||||
* i386-protos.h (ix86_secondary_memory_needed,
|
||||
ix86_preferred_reload_class, ix86_register_move_cost): Declare.
|
||||
* i386.c (ix86_secondary_memory_needed,
|
||||
ix86_preferred_reload_class, ix86_register_move_cost): New function.
|
||||
|
||||
Die Feb 13 11:04:25 CET 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* i386.h (VALID_FP_MODE_P, VALID_INT_MODE_P): New.
|
||||
|
|
|
@ -8725,6 +8725,108 @@ ix86_free_from_memory (mode)
|
|||
: 4))));
|
||||
}
|
||||
|
||||
/* Put float CONST_DOUBLE in the constant pool instead of fp regs.
|
||||
QImode must go into class Q_REGS.
|
||||
Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and
|
||||
movdf to do mem-to-mem moves through integer regs. */
|
||||
enum reg_class
|
||||
ix86_preferred_reload_class (x, class)
|
||||
rtx x;
|
||||
enum reg_class class;
|
||||
{
|
||||
if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
|
||||
{
|
||||
/* SSE can't load any constant directly yet. */
|
||||
if (SSE_CLASS_P (class))
|
||||
return NO_REGS;
|
||||
/* Floats can load 0 and 1. */
|
||||
if (MAYBE_FLOAT_CLASS_P (class) && standard_80387_constant_p (x))
|
||||
{
|
||||
/* Limit class to non-SSE. Use GENERAL_REGS if possible. */
|
||||
if (MAYBE_SSE_CLASS_P (class))
|
||||
return (reg_class_subset_p (class, GENERAL_REGS)
|
||||
? GENERAL_REGS : FLOAT_REGS);
|
||||
else
|
||||
return class;
|
||||
}
|
||||
/* General regs can load everything. */
|
||||
if (reg_class_subset_p (class, GENERAL_REGS))
|
||||
return GENERAL_REGS;
|
||||
/* In case we haven't resolved FLOAT or SSE yet, give up. */
|
||||
if (MAYBE_FLOAT_CLASS_P (class) || MAYBE_SSE_CLASS_P (class))
|
||||
return NO_REGS;
|
||||
}
|
||||
if (MAYBE_MMX_CLASS_P (class) && CONSTANT_P (x))
|
||||
return NO_REGS;
|
||||
if (GET_MODE (x) == QImode && ! reg_class_subset_p (class, Q_REGS))
|
||||
return Q_REGS;
|
||||
return class;
|
||||
}
|
||||
|
||||
/* If we are copying between general and FP registers, we need a memory
|
||||
location. The same is true for SSE and MMX registers.
|
||||
|
||||
The macro can't work reliably when one of the CLASSES is class containing
|
||||
registers from multiple units (SSE, MMX, integer). We avoid this by never
|
||||
combining those units in single alternative in the machine description.
|
||||
Ensure that this constraint holds to avoid unexpected surprises.
|
||||
|
||||
When STRICT is false, we are being called from REGISTER_MOVE_COST, so do not
|
||||
enforce these sanity checks. */
|
||||
int
|
||||
ix86_secondary_memory_needed (class1, class2, mode, strict)
|
||||
enum reg_class class1, class2;
|
||||
enum machine_mode mode;
|
||||
int strict;
|
||||
{
|
||||
if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
|
||||
|| MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
|
||||
|| MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
|
||||
|| MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
|
||||
|| MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
|
||||
|| MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2))
|
||||
{
|
||||
if (strict)
|
||||
abort ();
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
return (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)
|
||||
|| (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
|
||||
&& (mode) != SImode)
|
||||
|| (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
|
||||
&& (mode) != SImode));
|
||||
}
|
||||
/* Return the cost of moving data from a register in class CLASS1 to
|
||||
one in class CLASS2.
|
||||
|
||||
It is not required that the cost always equal 2 when FROM is the same as TO;
|
||||
on some machines it is expensive to move between registers if they are not
|
||||
general registers. */
|
||||
int
|
||||
ix86_register_move_cost (mode, class1, class2)
|
||||
enum machine_mode mode;
|
||||
enum reg_class class1, class2;
|
||||
{
|
||||
/* In case we require secondary memory, compute cost of the store followed
|
||||
by load. In case of copying from general_purpose_register we may emit
|
||||
multiple stores followed by single load causing memory size mismatch
|
||||
stall. Count this as arbitarily high cost of 20. */
|
||||
if (ix86_secondary_memory_needed (class1, class2, mode, 0))
|
||||
{
|
||||
if (CLASS_MAX_NREGS (CLASS1, MODE) > CLASS_MAX_NREGS (CLASS2, MODE))
|
||||
return 10;
|
||||
return (MEMORY_MOVE_COST (MODE, CLASS1, 0)
|
||||
+ MEMORY_MOVE_COST (MODE, CLASS2, 1));
|
||||
}
|
||||
/* Moves between SSE/MMX and integer unit are expensive.
|
||||
??? We should make this cost CPU specific. */
|
||||
if (MMX_CLASS_P (CLASS1) != MMX_CLASS_P (CLASS2)
|
||||
|| SSE_CLASS_P (CLASS1) != SSE_CLASS_P (CLASS2))
|
||||
return 3;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
|
||||
int
|
||||
ix86_hard_regno_mode_ok (regno, mode)
|
||||
|
|
|
@ -946,6 +946,11 @@ enum reg_class
|
|||
#define N_REG_CLASSES (int) LIM_REG_CLASSES
|
||||
|
||||
#define FLOAT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, FLOAT_REGS))
|
||||
#define SSE_CLASS_P(CLASS) (reg_class_subset_p (CLASS, SSE_REGS))
|
||||
#define MMX_CLASS_P(CLASS) (reg_class_subset_p (CLASS, MMX_REGS))
|
||||
#define MAYBE_FLOAT_CLASS_P(CLASS) (reg_classes_intersect_p (CLASS, FLOAT_REGS))
|
||||
#define MAYBE_SSE_CLASS_P(CLASS) (reg_classes_intersect_p (SSE_REGS, CLASS))
|
||||
#define MAYBE_MMX_CLASS_P(CLASS) (reg_classes_intersect_p (MMX_REGS, CLASS))
|
||||
|
||||
#define Q_CLASS_P(CLASS) (reg_class_subset_p (CLASS, Q_REGS))
|
||||
|
||||
|
@ -1112,22 +1117,12 @@ enum reg_class
|
|||
movdf to do mem-to-mem moves through integer regs. */
|
||||
|
||||
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
|
||||
(GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode \
|
||||
? (standard_80387_constant_p (X) \
|
||||
? CLASS \
|
||||
: (reg_class_subset_p (CLASS, FLOAT_REGS) \
|
||||
? NO_REGS \
|
||||
: reg_class_subset_p (CLASS, GENERAL_REGS) ? CLASS : GENERAL_REGS)) \
|
||||
: GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \
|
||||
: (CLASS))
|
||||
ix86_preferred_reload_class (X, CLASS)
|
||||
|
||||
/* If we are copying between general and FP registers, we need a memory
|
||||
location. */
|
||||
/* The same is true for SSE and MMX registers. */
|
||||
location. The same is true for SSE and MMX registers. */
|
||||
#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
|
||||
(FLOAT_CLASS_P (CLASS1) != FLOAT_CLASS_P (CLASS2) \
|
||||
|| ((CLASS1 == SSE_REGS) != (CLASS2 == SSE_REGS)) \
|
||||
|| ((CLASS1 == MMX_REGS) != (CLASS2 == MMX_REGS) && (MODE) != SImode))
|
||||
ix86_secondary_memory_needed (CLASS1, CLASS2, MODE, 1)
|
||||
|
||||
/* QImode spills from non-QI registers need a scratch. This does not
|
||||
happen often -- the only example so far requires an uninitialized
|
||||
|
@ -1141,7 +1136,7 @@ enum reg_class
|
|||
/* On the 80386, this is the size of MODE in words,
|
||||
except in the FP regs, where a single reg is always enough. */
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
(FLOAT_CLASS_P (CLASS) || (CLASS) == SSE_REGS || (CLASS) == MMX_REGS \
|
||||
(FLOAT_CLASS_P (CLASS) || SSE_CLASS_P (CLASS) || MMX_CLASS_P (CLASS) \
|
||||
? 1 \
|
||||
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
|
||||
|
||||
|
@ -2352,25 +2347,10 @@ while (0)
|
|||
|
||||
It is not required that the cost always equal 2 when FROM is the same as TO;
|
||||
on some machines it is expensive to move between registers if they are not
|
||||
general registers.
|
||||
general registers. */
|
||||
|
||||
On the i386, copying between floating-point and fixed-point
|
||||
registers is done trough memory.
|
||||
|
||||
Integer -> fp moves are noticeably slower than the opposite direction
|
||||
because of the partial memory stall they cause. Give it an
|
||||
arbitary high cost.
|
||||
*/
|
||||
|
||||
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
|
||||
((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2)) \
|
||||
? (MEMORY_MOVE_COST (DFmode, CLASS1, 0) \
|
||||
+ MEMORY_MOVE_COST (DFmode, CLASS2, 1)) \
|
||||
: (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2)) ? 10 \
|
||||
: ((CLASS1) == MMX_REGS && (CLASS2) == SSE_REGS) ? 10 \
|
||||
: ((CLASS1) == SSE_REGS && (CLASS2) == MMX_REGS) ? 10 \
|
||||
: ((CLASS1) == MMX_REGS) != ((CLASS2) == MMX_REGS) ? 3 \
|
||||
: 2)
|
||||
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
|
||||
ix86_register_move_cost (mode, class1, class2);
|
||||
|
||||
/* A C expression for the cost of moving data of mode M between a
|
||||
register and memory. A value of 2 is the default; this cost is
|
||||
|
|
Loading…
Add table
Reference in a new issue