The MOVC3 machine instruction has `memmove' semantics[1]:

"The operation of the instruction is such that overlap of the source and
destination strings does not affect the result."

so use it to provide the `movmemhi' instruction as well.

References:

[1] DEC STD 032-0 "VAX Architecture Standard", Digital Equipment
    Corporation, A-DS-EL-00032-00-0 Rev J, December 15, 1989, Section
    3.10 "Character-String Instructions", p. 3-162

        gcc/
        * config/vax/vax.md (cpymemhi1): Rename insn to...
        (movmemhi1): ... this.
        (cpymemhi): Update accordingly.  Remove constraints.
        (movmemhi): New expander.

        gcc/testsuite/
        * gcc.target/vax/movmem.c: New test.
---
 gcc/config/vax/vax.md                 | 24 ++++++++++++++++++------
 gcc/testsuite/gcc.target/vax/movmem.c | 23 +++++++++++++++++++++++
 2 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/vax/movmem.c

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 66f03df1932..f8e1c2eb02b 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -206,16 +206,28 @@ (define_insn "movstrictqi"
 }")
 
 ;; This is here to accept 4 arguments and pass the first 3 along
-;; to the cpymemhi1 pattern that really does the work.
+;; to the movmemhi1 pattern that really does the work.
 (define_expand "cpymemhi"
-  [(set (match_operand:BLK 0 "general_operand" "=g")
-       (match_operand:BLK 1 "general_operand" "g"))
-   (use (match_operand:HI 2 "general_operand" "g"))
+  [(set (match_operand:BLK 0 "memory_operand" "")
+       (match_operand:BLK 1 "memory_operand" ""))
+   (use (match_operand:HI 2 "general_operand" ""))
+   (match_operand 3 "" "")]
+  ""
+  "
+{
+  emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
+  DONE;
+}")
+
+(define_expand "movmemhi"
+  [(set (match_operand:BLK 0 "memory_operand" "")
+       (match_operand:BLK 1 "memory_operand" ""))
+   (use (match_operand:HI 2 "general_operand" ""))
    (match_operand 3 "" "")]
   ""
   "
 {
-  emit_insn (gen_cpymemhi1 (operands[0], operands[1], operands[2]));
+  emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
   DONE;
 }")
 
@@ -224,7 +236,7 @@ (define_expand "cpymemhi"
 ;; that anything generated as this insn will be recognized as one
 ;; and that it won't successfully combine with anything.
 
-(define_insn "cpymemhi1"
+(define_insn "movmemhi1"
   [(set (match_operand:BLK 0 "memory_operand" "=o")
        (match_operand:BLK 1 "memory_operand" "o"))
    (use (match_operand:HI 2 "general_operand" "g"))
diff --git a/gcc/testsuite/gcc.target/vax/movmem.c 
b/gcc/testsuite/gcc.target/vax/movmem.c
new file mode 100644
index 00000000000..b907d8a376d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/movmem.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+#include <stddef.h>
+
+void *
+memmove8 (void *to, const void *from, size_t size)
+{
+  unsigned char s8 = size;
+  return __builtin_memmove (to, from, s8);
+}
+
+/* Expect assembly like:
+
+       movl 4(%ap),%r6
+       movzbl 12(%ap),%r7
+       movl 8(%ap),%r8
+       movc3 %r7,(%r8),(%r6)
+       movl %r6,%r0
+
+ */
+
+/* { dg-final { scan-assembler "\tmovc3 " } } */
-- 
2.11.0

Reply via email to