aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-02-14 22:16:35 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2001-02-14 21:16:35 +0000
commitfa79946ef552152e732152ad7ffd127922ac9a60 (patch)
tree50f6669a210386b4c272ed2036c5330206d8a126
parent6836e0240ee7235a72c236ed8fa688759ec15e47 (diff)
downloadgcc-fa79946ef552152e732152ad7ffd127922ac9a60.zip
gcc-fa79946ef552152e732152ad7ffd127922ac9a60.tar.gz
gcc-fa79946ef552152e732152ad7ffd127922ac9a60.tar.bz2
i386-protos.h (ix86_memory_move_cost): Move offline.
* i386-protos.h (ix86_memory_move_cost): Move offline. * i386.c (ix86_register_move_cost): Compute properly cost of SSE, MMX and i387 instructions. (*_cost): Add costs of SSE/MMX moves. (ix86_memory_move_cost): Move offline from ....; Likewise. * i386.h (MEMORY_MOVE_COST): .... here; (struct processor costs): Add new fields to represent costs of SSE/MMX moves. From-SVN: r39689
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c179
-rw-r--r--gcc/config/i386/i386.h36
4 files changed, 200 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 732e24a..f7bb9a0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+Wed Feb 14 11:12:38 CET 2001 Jan Hubicka <jh@suse.cz>
+
+ * i386-protos.h (ix86_memory_move_cost): Move offline.
+ * i386.c (ix86_register_move_cost): Compute properly cost of
+ SSE, MMX and i387 instructions.
+ (*_cost): Add costs of SSE/MMX moves.
+ (ix86_memory_move_cost): Move offline from ....; Likewise.
+ * i386.h (MEMORY_MOVE_COST): .... here;
+ (struct processor costs): Add new fields to represent costs
+ of SSE/MMX moves.
+
Wed Feb 14 10:08:26 CET 2001 Jan Hubicka <jh@suse.cz>
* regclass.c (init_reg_sets_1): Reinstall the optimization of
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 708bb0f..0e0a520 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -139,6 +139,8 @@ extern int ix86_secondary_memory_needed PARAMS ((enum reg_class,
enum machine_mode, int));
extern enum reg_class ix86_preferred_reload_class PARAMS ((rtx,
enum reg_class));
+extern int ix86_memory_move_cost PARAMS ((enum machine_mode, enum reg_class,
+ int));
#ifdef TREE_CODE
extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0ef4acc..222dbf7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -65,7 +65,18 @@ struct processor_costs i386_cost = { /* 386 specific costs */
2, /* cost of reg,reg fld/fst */
{8, 8, 8}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {8, 8, 8} /* cost of loading integer registers */
+ {8, 8, 8}, /* cost of loading integer registers */
+ 2, /* cost of moving MMX register */
+ {4, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {4, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {4, 8, 16}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {4, 8, 16}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 3, /* MMX or SSE register to integer */
};
struct processor_costs i486_cost = { /* 486 specific costs */
@@ -86,7 +97,18 @@ struct processor_costs i486_cost = { /* 486 specific costs */
2, /* cost of reg,reg fld/fst */
{8, 8, 8}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {8, 8, 8} /* cost of loading integer registers */
+ {8, 8, 8}, /* cost of loading integer registers */
+ 2, /* cost of moving MMX register */
+ {4, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {4, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {4, 8, 16}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {4, 8, 16}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 3 /* MMX or SSE register to integer */
};
struct processor_costs pentium_cost = {
@@ -107,7 +129,18 @@ struct processor_costs pentium_cost = {
2, /* cost of reg,reg fld/fst */
{2, 2, 6}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {4, 4, 6} /* cost of loading integer registers */
+ {4, 4, 6}, /* cost of loading integer registers */
+ 8, /* cost of moving MMX register */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {8, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {4, 8, 16}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {4, 8, 16}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 3 /* MMX or SSE register to integer */
};
struct processor_costs pentiumpro_cost = {
@@ -128,7 +161,18 @@ struct processor_costs pentiumpro_cost = {
2, /* cost of reg,reg fld/fst */
{2, 2, 6}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {4, 4, 6} /* cost of loading integer registers */
+ {4, 4, 6}, /* cost of loading integer registers */
+ 2, /* cost of moving MMX register */
+ {2, 2}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {2, 2}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {2, 2, 8}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {2, 2, 8}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 3 /* MMX or SSE register to integer */
};
struct processor_costs k6_cost = {
@@ -149,7 +193,18 @@ struct processor_costs k6_cost = {
4, /* cost of reg,reg fld/fst */
{6, 6, 6}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {4, 4, 4} /* cost of loading integer registers */
+ {4, 4, 4}, /* cost of loading integer registers */
+ 2, /* cost of moving MMX register */
+ {2, 2}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {2, 2}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {2, 2, 8}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {2, 2, 8}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 6 /* MMX or SSE register to integer */
};
struct processor_costs athlon_cost = {
@@ -170,7 +225,18 @@ struct processor_costs athlon_cost = {
4, /* cost of reg,reg fld/fst */
{6, 6, 20}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {4, 4, 16} /* cost of loading integer registers */
+ {4, 4, 16}, /* cost of loading integer registers */
+ 2, /* cost of moving MMX register */
+ {2, 2}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {2, 2}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {2, 2, 8}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {2, 2, 8}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 6 /* MMX or SSE register to integer */
};
struct processor_costs *ix86_cost = &pentium_cost;
@@ -8854,7 +8920,13 @@ ix86_register_move_cost (mode, class1, class2)
??? 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 ix86_cost->mmxsse_to_integer;
+ if (MAYBE_FLOAT_CLASS_P (class1))
+ return ix86_cost->fp_move;
+ if (MAYBE_SSE_CLASS_P (class1))
+ return ix86_cost->sse_move;
+ if (MAYBE_MMX_CLASS_P (class1))
+ return ix86_cost->mmx_move;
return 2;
}
@@ -8887,3 +8959,96 @@ ix86_hard_regno_mode_ok (regno, mode)
return 1;
return reload_in_progress || reload_completed || !TARGET_PARTIAL_REG_STALL;
}
+
+/* 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'.
+
+ If moving between registers and memory is more expensive than
+ between two registers, you should define this macro to express the
+ relative cost.
+
+ Model also increased moving costs of QImode registers in non
+ Q_REGS classes.
+ */
+int
+ix86_memory_move_cost (mode, class, in)
+ enum machine_mode mode;
+ enum reg_class class;
+ int in;
+{
+ if (FLOAT_CLASS_P (class))
+ {
+ int index;
+ switch (mode)
+ {
+ case SFmode:
+ index = 0;
+ break;
+ case DFmode:
+ index = 1;
+ break;
+ case XFmode:
+ case TFmode:
+ index = 2;
+ break;
+ default:
+ return 100;
+ }
+ return in ? ix86_cost->fp_load [index] : ix86_cost->fp_store [index];
+ }
+ if (SSE_CLASS_P (class))
+ {
+ int index;
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 4:
+ index = 0;
+ break;
+ case 8:
+ index = 1;
+ break;
+ case 16:
+ index = 2;
+ break;
+ default:
+ return 100;
+ }
+ return in ? ix86_cost->sse_load [index] : ix86_cost->sse_store [index];
+ }
+ if (MMX_CLASS_P (class))
+ {
+ int index;
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 4:
+ index = 0;
+ break;
+ case 8:
+ index = 1;
+ break;
+ default:
+ return 100;
+ }
+ return in ? ix86_cost->mmx_load [index] : ix86_cost->mmx_store [index];
+ }
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 1:
+ if (in)
+ return (Q_CLASS_P (class) ? ix86_cost->int_load[0]
+ : ix86_cost->movzbl_load);
+ else
+ return (Q_CLASS_P (class) ? ix86_cost->int_store[0]
+ : ix86_cost->int_store[0] + 4);
+ break;
+ case 2:
+ return in ? ix86_cost->int_load[1] : ix86_cost->int_store[1];
+ default:
+ /* Compute number of 32bit moves needed. TFmode is moved as XFmode. */
+ if (mode == TFmode)
+ mode = XFmode;
+ return ((in ? ix86_cost->int_load[1] : ix86_cost->int_store[1])
+ * (int) GET_MODE_SIZE (mode) / 4);
+ }
+}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 1dd722c..d97d988 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -72,6 +72,18 @@ struct processor_costs {
in SFmode, DFmode and XFmode */
int fp_store[3]; /* cost of storing FP register
in SFmode, DFmode and XFmode */
+ int mmx_move; /* cost of moving MMX register. */
+ int mmx_load[2]; /* cost of loading MMX register
+ in SImode and DImode */
+ int mmx_store[2]; /* cost of storing MMX register
+ in SImode and DImode */
+ int sse_move; /* cost of moving SSE register. */
+ int sse_load[3]; /* cost of loading SSE register
+ in SImode, DImode and TImode*/
+ int sse_store[3]; /* cost of storing SSE register
+ in SImode, DImode and TImode*/
+ int mmxsse_to_integer; /* cost of moving mmxsse register to
+ integer and vice versa. */
};
extern struct processor_costs *ix86_cost;
@@ -2395,28 +2407,10 @@ while (0)
If moving between registers and memory is more expensive than
between two registers, you should define this macro to express the
- relative cost.
-
- Model also increased moving costs of QImode registers in non
- Q_REGS classes.
- */
+ relative cost. */
-#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
- (FLOAT_CLASS_P (CLASS) \
- ? (GET_MODE_SIZE (MODE)==4 \
- ? (IN ? ix86_cost->fp_load[0] : ix86_cost->fp_store[0]) \
- : (GET_MODE_SIZE (MODE)==8 \
- ? (IN ? ix86_cost->fp_load[1] : ix86_cost->fp_store[1]) \
- : (IN ? ix86_cost->fp_load[2] : ix86_cost->fp_store[2]))) \
- : (GET_MODE_SIZE (MODE)==1 \
- ? (IN ? (Q_CLASS_P (CLASS) ? ix86_cost->int_load[0] \
- : ix86_cost->movzbl_load) \
- : (Q_CLASS_P (CLASS) ? ix86_cost->int_store[0] \
- : ix86_cost->int_store[0] + 4)) \
- : (GET_MODE_SIZE (MODE)==2 \
- ? (IN ? ix86_cost->int_load[1] : ix86_cost->int_store[1]) \
- : ((IN ? ix86_cost->int_load[2] : ix86_cost->int_store[2]) \
- * (int) GET_MODE_SIZE (MODE) / 4))))
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
+ ix86_memory_move_cost (MODE, CLASS, IN)
/* A C expression for the cost of a branch instruction. A value of 1
is the default; other values are interpreted relative to that. */