diff options
author | Chao-ying Fu <fu@mips.com> | 2009-10-29 07:08:03 +0000 |
---|---|---|
committer | Chao-ying Fu <chaoyingfu@gcc.gnu.org> | 2009-10-29 07:08:03 +0000 |
commit | d48a31968cd46215e7353b7e0a840df9ed3c4fba (patch) | |
tree | 90d4933665b6a8903ddffdaef5e3e06df80b8951 /gcc | |
parent | 18ab0fc8c7cbed25c1f985a42cb6bca3e9d98641 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 53 |
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. |