aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@gmail.com>2018-03-11 08:24:33 +0000
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>2018-03-11 08:24:33 +0000
commit483c57af553b22721f46bfdbd2795ac004767a51 (patch)
tree1ea95eb6e07517701cc160efd267f7ff3f22d2a6 /gcc
parent3999578cc522eb57d65c00c9293ca88cfbd901c2 (diff)
downloadgcc-483c57af553b22721f46bfdbd2795ac004767a51.zip
gcc-483c57af553b22721f46bfdbd2795ac004767a51.tar.gz
gcc-483c57af553b22721f46bfdbd2795ac004767a51.tar.bz2
[NDS32] Implement strlensi pattern.
gcc/ * config/nds32/nds32-memory-manipulation.c (nds32_expand_strlen): New function. * config/nds32/nds32-multiple.md (strlensi): New pattern. * config/nds32/nds32-protos.h (nds32_expand_strlen): Declare function. Co-Authored-By: Chung-Ju Wu <jasonwucj@gmail.com> From-SVN: r258425
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/nds32/nds32-memory-manipulation.c63
-rw-r--r--gcc/config/nds32/nds32-multiple.md13
-rw-r--r--gcc/config/nds32/nds32-protos.h1
4 files changed, 85 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0cdc24f..d429cd2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2018-03-11 Kito Cheng <kito.cheng@gmail.com>
+ Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/nds32-memory-manipulation.c (nds32_expand_strlen): New
+ function.
+ * config/nds32/nds32-multiple.md (strlensi): New pattern.
+ * config/nds32/nds32-protos.h (nds32_expand_strlen): Declare function.
+
2018-03-11 Monk Chiang <sh.chiang04@gmail.com>
Kito Cheng <kito.cheng@gmail.com>
Chung-Ju Wu <jasonwucj@gmail.com>
diff --git a/gcc/config/nds32/nds32-memory-manipulation.c b/gcc/config/nds32/nds32-memory-manipulation.c
index 13ac8c1..8dea130 100644
--- a/gcc/config/nds32/nds32-memory-manipulation.c
+++ b/gcc/config/nds32/nds32-memory-manipulation.c
@@ -848,6 +848,69 @@ nds32_expand_setmem (rtx dstmem, rtx size, rtx value, rtx align,
/* ------------------------------------------------------------------------ */
+/* Auxiliary function for expand strlen pattern. */
+
+bool
+nds32_expand_strlen (rtx result, rtx str,
+ rtx target_char, rtx align ATTRIBUTE_UNUSED)
+{
+ rtx base_reg, backup_base_reg;
+ rtx ffb_result;
+ rtx target_char_ptr, length;
+ rtx loop_label, tmp;
+
+ if (optimize_size || optimize < 3)
+ return false;
+
+ gcc_assert (MEM_P (str));
+ gcc_assert (CONST_INT_P (target_char) || REG_P (target_char));
+
+ base_reg = copy_to_mode_reg (SImode, XEXP (str, 0));
+ loop_label = gen_label_rtx ();
+
+ ffb_result = gen_reg_rtx (Pmode);
+ tmp = gen_reg_rtx (SImode);
+ backup_base_reg = gen_reg_rtx (SImode);
+
+ /* Emit loop version of strlen.
+ move $backup_base, $base
+ .Lloop:
+ lmw.bim $tmp, [$base], $tmp, 0
+ ffb $ffb_result, $tmp, $target_char ! is there $target_char?
+ beqz $ffb_result, .Lloop
+ add $last_char_ptr, $base, $ffb_result
+ sub $length, $last_char_ptr, $backup_base */
+
+ /* move $backup_base, $base */
+ emit_move_insn (backup_base_reg, base_reg);
+
+ /* .Lloop: */
+ emit_label (loop_label);
+ /* lmw.bim $tmp, [$base], $tmp, 0 */
+ emit_insn (gen_unaligned_load_update_base_w (base_reg, tmp, base_reg));
+
+ /* ffb $ffb_result, $tmp, $target_char ! is there $target_char? */
+ emit_insn (gen_unspec_ffb (ffb_result, tmp, target_char));
+
+ /* beqz $ffb_result, .Lloop */
+ emit_cmp_and_jump_insns (ffb_result, const0_rtx, EQ, NULL,
+ SImode, 1, loop_label);
+
+ /* add $target_char_ptr, $base, $ffb_result */
+ target_char_ptr = expand_binop (Pmode, add_optab, base_reg,
+ ffb_result, NULL_RTX, 0, OPTAB_WIDEN);
+
+ /* sub $length, $target_char_ptr, $backup_base */
+ length = expand_binop (Pmode, sub_optab, target_char_ptr,
+ backup_base_reg, NULL_RTX, 0, OPTAB_WIDEN);
+
+ emit_move_insn (result, length);
+
+ return true;
+}
+
+/* ------------------------------------------------------------------------ */
+
/* Functions to expand load_multiple and store_multiple.
They are auxiliary extern functions to help create rtx template.
Check nds32-multiple.md file for the patterns. */
diff --git a/gcc/config/nds32/nds32-multiple.md b/gcc/config/nds32/nds32-multiple.md
index 66880c2..a8f7717 100644
--- a/gcc/config/nds32/nds32-multiple.md
+++ b/gcc/config/nds32/nds32-multiple.md
@@ -3750,6 +3750,19 @@
;; ------------------------------------------------------------------------
+(define_expand "strlensi"
+ [(match_operand:SI 0 "register_operand")
+ (match_operand:BLK 1 "memory_operand")
+ (match_operand:QI 2 "nds32_reg_constant_operand")
+ (match_operand 3 "const_int_operand")]
+ "TARGET_EXT_STRING"
+{
+ if (nds32_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
+ DONE;
+
+ FAIL;
+})
+
(define_expand "setmemsi"
[(use (match_operand:BLK 0 "memory_operand"))
(use (match_operand:SI 1 "nds32_reg_constant_operand"))
diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h
index 075206e..e1522f9 100644
--- a/gcc/config/nds32/nds32-protos.h
+++ b/gcc/config/nds32/nds32-protos.h
@@ -70,6 +70,7 @@ extern rtx nds32_expand_load_multiple (int, int, rtx, rtx, bool, rtx *);
extern rtx nds32_expand_store_multiple (int, int, rtx, rtx, bool, rtx *);
extern bool nds32_expand_movmemsi (rtx, rtx, rtx, rtx);
extern bool nds32_expand_setmem (rtx, rtx, rtx, rtx, rtx, rtx);
+extern bool nds32_expand_strlen (rtx, rtx, rtx, rtx);
/* Auxiliary functions for expand unalign load instruction. */