Commit 2c893b9d by Uros Bizjak Committed by Uros Bizjak

i386.c (ix86_emit_binop): New static function.

	* config/i386/i386.c (ix86_emit_binop): New static function.
	(ix86_split_lea_for_addr): Use ix86_emit_binop to emit add and shl
	instructions.
	(x86_output_mi_thunk): Use ix86_emit_binop to emit add instructions.

From-SVN: r179537
parent 6f37c8d4
2011-10-05 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (ix86_emit_binop): New static function.
(ix86_split_lea_for_addr): Use ix86_emit_binop to emit add and shl
instructions.
(x86_output_mi_thunk): Use ix86_emit_binop to emit add instructions.
2011-10-04 David S. Miller <davem@davemloft.net> 2011-10-04 David S. Miller <davem@davemloft.net>
* config/sparc/sparc.md (UNSPEC_FHADD, UNSPEC_FHSUB, * config/sparc/sparc.md (UNSPEC_FHADD, UNSPEC_FHSUB,
...@@ -16470,6 +16470,21 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[]) ...@@ -16470,6 +16470,21 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost); return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost);
} }
/* Emit x86 binary operand CODE in mode MODE, where the first operand
matches destination. RTX includes clobber of FLAGS_REG. */
static void
ix86_emit_binop (enum rtx_code code, enum machine_mode mode,
rtx dst, rtx src)
{
rtx op, clob;
op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, mode, dst, src));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
}
/* Split lea instructions into a sequence of instructions /* Split lea instructions into a sequence of instructions
which are executed on ALU to avoid AGU stalls. which are executed on ALU to avoid AGU stalls.
It is assumed that it is allowed to clobber flags register It is assumed that it is allowed to clobber flags register
...@@ -16482,8 +16497,7 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode) ...@@ -16482,8 +16497,7 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode)
unsigned int regno1 = INVALID_REGNUM; unsigned int regno1 = INVALID_REGNUM;
unsigned int regno2 = INVALID_REGNUM; unsigned int regno2 = INVALID_REGNUM;
struct ix86_address parts; struct ix86_address parts;
rtx tmp, clob; rtx tmp;
rtvec par;
int ok, adds; int ok, adds;
ok = ix86_decompose_address (operands[1], &parts); ok = ix86_decompose_address (operands[1], &parts);
...@@ -16515,14 +16529,7 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode) ...@@ -16515,14 +16529,7 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode)
gcc_assert (regno2 != regno0); gcc_assert (regno2 != regno0);
for (adds = parts.scale; adds > 0; adds--) for (adds = parts.scale; adds > 0; adds--)
{ ix86_emit_binop (PLUS, mode, operands[0], parts.index);
tmp = gen_rtx_PLUS (mode, operands[0], parts.index);
tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
clob = gen_rtx_CLOBBER (VOIDmode,
gen_rtx_REG (CCmode, FLAGS_REG));
par = gen_rtvec (2, tmp, clob);
emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
}
} }
else else
{ {
...@@ -16531,30 +16538,14 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode) ...@@ -16531,30 +16538,14 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.index)); emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.index));
/* Use shift for scaling. */ /* Use shift for scaling. */
tmp = gen_rtx_ASHIFT (mode, operands[0], ix86_emit_binop (ASHIFT, mode, operands[0],
GEN_INT (exact_log2 (parts.scale))); GEN_INT (exact_log2 (parts.scale)));
tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
par = gen_rtvec (2, tmp, clob);
emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
if (parts.base) if (parts.base)
{ ix86_emit_binop (PLUS, mode, operands[0], parts.base);
tmp = gen_rtx_PLUS (mode, operands[0], parts.base);
tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
par = gen_rtvec (2, tmp, clob);
emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
}
if (parts.disp && parts.disp != const0_rtx) if (parts.disp && parts.disp != const0_rtx)
{ ix86_emit_binop (PLUS, mode, operands[0], parts.disp);
tmp = gen_rtx_PLUS (mode, operands[0], parts.disp);
tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
par = gen_rtvec (2, tmp, clob);
emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
}
} }
} }
else if (!parts.base && !parts.index) else if (!parts.base && !parts.index)
...@@ -16565,41 +16556,32 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode) ...@@ -16565,41 +16556,32 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode)
else else
{ {
if (!parts.base) if (!parts.base)
{ {
if (regno0 != regno2) if (regno0 != regno2)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.index)); emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.index));
} }
else if (!parts.index) else if (!parts.index)
{ {
if (regno0 != regno1) if (regno0 != regno1)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.base));
}
else
{
if (regno0 == regno1)
tmp = gen_rtx_PLUS (mode, operands[0], parts.index);
else if (regno0 == regno2)
tmp = gen_rtx_PLUS (mode, operands[0], parts.base);
else
{
emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.base)); emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.base));
tmp = gen_rtx_PLUS (mode, operands[0], parts.index); }
} else
{
if (regno0 == regno1)
tmp = parts.index;
else if (regno0 == regno2)
tmp = parts.base;
else
{
emit_insn (gen_rtx_SET (VOIDmode, operands[0], parts.base));
tmp = parts.index;
}
tmp = gen_rtx_SET (VOIDmode, operands[0], tmp); ix86_emit_binop (PLUS, mode, operands[0], tmp);
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); }
par = gen_rtvec (2, tmp, clob);
emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
}
if (parts.disp && parts.disp != const0_rtx) if (parts.disp && parts.disp != const0_rtx)
{ ix86_emit_binop (PLUS, mode, operands[0], parts.disp);
tmp = gen_rtx_PLUS (mode, operands[0], parts.disp);
tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
par = gen_rtvec (2, tmp, clob);
emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
}
} }
} }
...@@ -30940,7 +30922,7 @@ x86_output_mi_thunk (FILE *file, ...@@ -30940,7 +30922,7 @@ x86_output_mi_thunk (FILE *file,
} }
} }
emit_insn (ix86_gen_add3 (delta_dst, delta_dst, delta_rtx)); ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
} }
/* Adjust the this parameter by a value stored in the vtable. */ /* Adjust the this parameter by a value stored in the vtable. */
...@@ -30983,7 +30965,7 @@ x86_output_mi_thunk (FILE *file, ...@@ -30983,7 +30965,7 @@ x86_output_mi_thunk (FILE *file,
REGNO (this_reg)), REGNO (this_reg)),
vcall_mem)); vcall_mem));
else else
emit_insn (ix86_gen_add3 (this_reg, this_reg, vcall_mem)); ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
} }
/* If necessary, drop THIS back to its stack slot. */ /* If necessary, drop THIS back to its stack slot. */
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