aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChao-ying Fu <fu@mips.com>2009-10-29 07:08:03 +0000
committerChao-ying Fu <chaoyingfu@gcc.gnu.org>2009-10-29 07:08:03 +0000
commitd48a31968cd46215e7353b7e0a840df9ed3c4fba (patch)
tree90d4933665b6a8903ddffdaef5e3e06df80b8951 /gcc
parent18ab0fc8c7cbed25c1f985a42cb6bca3e9d98641 (diff)
downloadgcc-d48a31968cd46215e7353b7e0a840df9ed3c4fba.zip
gcc-d48a31968cd46215e7353b7e0a840df9ed3c4fba.tar.gz
gcc-d48a31968cd46215e7353b7e0a840df9ed3c4fba.tar.bz2
mips.c (mips_emit_unary, [...]): New functions.
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: r153696
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/mips/mips.c53
2 files changed, 58 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 90221df..98d35a3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+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-10-28 Rafael Avila de Espindola <espindola@google.com>
* doc/invoke.texi: Rename -use-linker-plugin -fuse-linker-plugin.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index f82091a..6af8d03 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2444,6 +2444,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
@@ -6689,7 +6711,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);
@@ -6697,18 +6726,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.