backport: mips.c (mips_emit_unary, [...]): New functions.

2009-11-10  Chao-ying Fu  <fu@mips.com>

	Backport from mainline
	2009-10-29  Chao-ying Fu  <fu@mips.com>

	* config/mips/mips.c (mips_emit_unary, mips_force_unary): New
	functions.
	(mips_expand_synci_loop):  Use the length rtx to control the
	synci loop from the begin rtx that points to the first byte of
	the cache line.

From-SVN: r154080
This commit is contained in:
Chao-ying Fu 2009-11-10 22:35:18 +00:00 committed by Chao-ying Fu
parent e67657e678
commit bbf1202ece
2 changed files with 61 additions and 3 deletions

View File

@ -1,3 +1,14 @@
2009-11-10 Chao-ying Fu <fu@mips.com>
Backport from mainline
2009-10-29 Chao-ying Fu <fu@mips.com>
* config/mips/mips.c (mips_emit_unary, mips_force_unary): New
functions.
(mips_expand_synci_loop): Use the length rtx to control the
synci loop from the begin rtx that points to the first byte of
the cache line.
2009-11-09 Jakub Jelinek <jakub@redhat.com>
PR middle-end/40946

View File

@ -2328,6 +2328,28 @@ mips_emit_move (rtx dest, rtx src)
: emit_move_insn_1 (dest, src));
}
/* Emit an instruction of the form (set TARGET (CODE OP0)). */
static void
mips_emit_unary (enum rtx_code code, rtx target, rtx op0)
{
emit_insn (gen_rtx_SET (VOIDmode, target,
gen_rtx_fmt_e (code, GET_MODE (op0), op0)));
}
/* Compute (CODE OP0) and store the result in a new register of mode MODE.
Return that new register. */
static rtx
mips_force_unary (enum machine_mode mode, enum rtx_code code, rtx op0)
{
rtx reg;
reg = gen_reg_rtx (mode);
mips_emit_unary (code, reg, op0);
return reg;
}
/* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
static void
@ -6399,7 +6421,14 @@ mips_expand_block_move (rtx dest, rtx src, rtx length)
void
mips_expand_synci_loop (rtx begin, rtx end)
{
rtx inc, label, cmp, cmp_result;
rtx inc, label, end_label, cmp_result, mask, length;
/* Create end_label. */
end_label = gen_label_rtx ();
/* Check if begin equals end. */
cmp_result = gen_rtx_EQ (VOIDmode, begin, end);
emit_jump_insn (gen_condjump (cmp_result, end_label));
/* Load INC with the cache line size (rdhwr INC,$1). */
inc = gen_reg_rtx (Pmode);
@ -6407,18 +6436,36 @@ mips_expand_synci_loop (rtx begin, rtx end)
? gen_rdhwr_synci_step_si (inc)
: gen_rdhwr_synci_step_di (inc));
/* Check if inc is 0. */
cmp_result = gen_rtx_EQ (VOIDmode, inc, const0_rtx);
emit_jump_insn (gen_condjump (cmp_result, end_label));
/* Calculate mask. */
mask = mips_force_unary (Pmode, NEG, inc);
/* Mask out begin by mask. */
begin = mips_force_binary (Pmode, AND, begin, mask);
/* Calculate length. */
length = mips_force_binary (Pmode, MINUS, end, begin);
/* Loop back to here. */
label = gen_label_rtx ();
emit_label (label);
emit_insn (gen_synci (begin));
cmp = mips_force_binary (Pmode, GTU, begin, end);
/* Update length. */
mips_emit_binary (MINUS, length, length, inc);
/* Update begin. */
mips_emit_binary (PLUS, begin, begin, inc);
cmp_result = gen_rtx_EQ (VOIDmode, cmp, const0_rtx);
/* Check if length is greater than 0. */
cmp_result = gen_rtx_GT (VOIDmode, length, const0_rtx);
emit_jump_insn (gen_condjump (cmp_result, label));
emit_label (end_label);
}
/* Expand a QI or HI mode atomic memory operation.