aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/compile-i386.c
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-03 18:31:07 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:02:35 -0700
commit50f15c801dba75e58b383b43c8d661adfa61db49 (patch)
tree46aad909bc4f9904be2e86888e061cebd04effb4 /compile-i386.c
parent407472d12d615c7ad3c3633a1aa8c89f2f84d54d (diff)
downloadsparse-dev-50f15c801dba75e58b383b43c8d661adfa61db49.tar.gz
Improve "emit_move()" handling.
If we are loading something into a register, and another register has that value already cached, used the cached register value.
Diffstat (limited to 'compile-i386.c')
-rw-r--r--compile-i386.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/compile-i386.c b/compile-i386.c
index ab7a229d..f51231e3 100644
--- a/compile-i386.c
+++ b/compile-i386.c
@@ -242,6 +242,11 @@ static struct storage hardreg_storage_table[] = {
DECLARE_BITMAP(regs_in_use, 256);
+static inline struct storage * reginfo_reg(struct reg_info *info)
+{
+ return hardreg_storage_table + info->own_regno;
+}
+
struct storage * get_hardreg(struct storage *reg, int clear)
{
struct reg_info *info = reg->reg;
@@ -1140,8 +1145,18 @@ static void emit_move(struct storage *src, struct storage *dest,
is_signed = 0;
}
+ /*
+ * Are we moving from a register to a register?
+ * Make the new reg to be the "cache".
+ */
if ((dest->type == STOR_REG) && (src->type == STOR_REG)) {
- struct storage *backing = src->reg->contains;
+ struct storage *backing;
+
+reg_reg_move:
+ if (dest == src)
+ return;
+
+ backing = src->reg->contains;
if (backing) {
/* Is it still valid? */
if (backing->reg != src->reg)
@@ -1154,17 +1169,30 @@ static void emit_move(struct storage *src, struct storage *dest,
return;
}
+ /*
+ * Are we moving to a register from a non-reg?
+ *
+ * See if we have the non-reg source already cached
+ * in a register..
+ */
+ if (dest->type == STOR_REG) {
+ if (src->reg) {
+ struct reg_info *info = src->reg;
+ if (info->contains == src) {
+ src = reginfo_reg(info);
+ goto reg_reg_move;
+ }
+ }
+ dest->reg->contains = src;
+ src->reg = dest->reg;
+ }
+
if (src->type == STOR_REG) {
/* We could just mark the register dirty here and do lazy store.. */
src->reg->contains = dest;
dest->reg = src->reg;
}
- if (dest->type == STOR_REG) {
- dest->reg->contains = src;
- src->reg = dest->reg;
- }
-
if ((bits == 8) || (bits == 16)) {
if (is_dest)
opname = "mov";