Repository : ssh://darcs.haskell.org//srv/darcs/testsuite

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/a351a67a242f8484764fe450b973b2d4ac9d098e

>---------------------------------------------------------------

commit a351a67a242f8484764fe450b973b2d4ac9d098e
Author: Johan Tibell <johan.tib...@gmail.com>
Date:   Tue May 31 11:56:58 2011 +0200

    Make it possible to test the generated assembly
    
    This test framework feature is inspired by a similar feature in LLVM.
    The programmer writes a bit of Cmm
    
        #include "Cmm.h"
    
        // Large memcpy's should lower to calls.
        callMemcpy
        {
          W_ dst, src;
          prim %memcpy(dst "ptr", src "ptr", 1024, 4) [];
        }
    
    and asserts what the generated assembly should look like, modulo
    register naming.
    
        callMemcpy:
        movq  ; Move arguments into place
        movq
        movl
        movl
        call memcpy
    
    Patch edited and updated by Simon Marlow, and I also added a test for
    unrolling memcpy and a simple constant-propagation test.

>---------------------------------------------------------------

 driver/testlib.py                                  |   54 +++++++++++++++++++-
 .../should_gen_asm}/Makefile                       |    0 
 tests/codeGen/should_gen_asm/all.T                 |    3 +
 .../should_gen_asm/memcpy-unroll-conprop.asm       |   21 ++++++++
 .../should_gen_asm/memcpy-unroll-conprop.cmm       |   14 +++++
 tests/codeGen/should_gen_asm/memcpy-unroll.asm     |   18 +++++++
 tests/codeGen/should_gen_asm/memcpy-unroll.cmm     |    8 +++
 tests/codeGen/should_gen_asm/memcpy.asm            |    9 +++
 tests/codeGen/should_gen_asm/memcpy.cmm            |    8 +++
 9 files changed, 134 insertions(+), 1 deletions(-)

diff --git a/driver/testlib.py b/driver/testlib.py
index 5853413..4531801 100644
--- a/driver/testlib.py
+++ b/driver/testlib.py
@@ -329,6 +329,12 @@ def if_arch( arch, f ):
     else:
         return normal
 
+def unless_arch( arch, f ):
+    if config.arch == arch:
+        return normal
+    else:
+        return f
+
 def if_wordsize( ws, f ):
     if config.wordsize == str(ws):
         return f
@@ -941,6 +947,33 @@ def do_compile( name, way, should_fail, top_mod, 
extra_mods, extra_hc_opts ):
     # no problems found, this test passed
     return passed()
 
+def compile_cmp_asm( name, way, extra_hc_opts ):
+    print 'Compile only, extra args = ', extra_hc_opts
+    pretest_cleanup(name)
+    result = simple_build( name + '.cmm', way, '-keep-s-files -O ' + 
extra_hc_opts, 0, '', 0, 0, 0)
+
+    if badResult(result):
+        return result
+
+    # the actual stderr should always match the expected, regardless
+    # of whether we expected the compilation to fail or not (successful
+    # compilations may generate warnings).
+
+    if getTestOpts().with_namebase == None:
+        namebase = name
+    else:
+        namebase = getTestOpts().with_namebase
+
+    (platform_specific, expected_asm_file) = 
platform_wordsize_qualify(namebase, 'asm')
+    actual_asm_file = qualify(name, 's')
+
+    if not compare_outputs('asm', two_normalisers(normalise_errmsg, 
normalise_asm), \
+                           expected_asm_file, actual_asm_file):
+        return failBecause('asm mismatch')
+
+    # no problems found, this test passed
+    return passed()
+
 # -----------------------------------------------------------------------------
 # Compile-and-run tests
 
@@ -1674,6 +1707,26 @@ def normalise_output( str ):
     str = re.sub('([^\\s])\\.exe', '\\1', str)
     return str
 
+def normalise_asm( str ):
+    lines = str.split('\n')
+    # Only keep instructions and labels not starting with a dot.
+    metadata = re.compile('^[ \t]*\\..*$')
+    out = []
+    for line in lines:
+      # Drop metadata directives (e.g. ".type")
+      if not metadata.match(line):
+        instr = line.lstrip().split()
+        # Drop empty lines.
+        if not instr:
+          continue
+        # Drop operands, except for call instructions.
+        elif instr[0] == 'call':
+          out.append(instr[0] + ' ' + instr[1])
+        else:
+          out.append(instr[0])
+    out = '\n'.join(out)
+    return out
+
 def if_verbose( n, str ):
     if config.verbose >= n:
         print str
@@ -2118,4 +2171,3 @@ def getStdout(cmd):
         return stdout
     else:
         raise Exception("Need subprocess to get stdout, but don't have it")
-
diff --git a/tests/annotations/should_compile/Makefile 
b/tests/codeGen/should_gen_asm/Makefile
similarity index 100%
copy from tests/annotations/should_compile/Makefile
copy to tests/codeGen/should_gen_asm/Makefile
diff --git a/tests/codeGen/should_gen_asm/all.T 
b/tests/codeGen/should_gen_asm/all.T
new file mode 100644
index 0000000..c262255
--- /dev/null
+++ b/tests/codeGen/should_gen_asm/all.T
@@ -0,0 +1,3 @@
+test('memcpy', unless_arch('x86_64',skip), compile_cmp_asm, [''])
+test('memcpy-unroll', unless_arch('x86_64',skip), compile_cmp_asm, [''])
+test('memcpy-unroll-conprop', unless_arch('x86_64',skip), compile_cmp_asm, 
[''])
diff --git a/tests/codeGen/should_gen_asm/memcpy-unroll-conprop.asm 
b/tests/codeGen/should_gen_asm/memcpy-unroll-conprop.asm
new file mode 100644
index 0000000..1bafb34
--- /dev/null
+++ b/tests/codeGen/should_gen_asm/memcpy-unroll-conprop.asm
@@ -0,0 +1,21 @@
+.text
+       .align 8
+.globl callMemcpy
+.type callMemcpy, @object
+callMemcpy:
+.Lc8:
+       testq %rbx,%rbx
+       je .Lcb
+       movl 0(%r14),%eax
+       movl %eax,0(%rbx)
+       movl 4(%r14),%eax
+       movl %eax,4(%rbx)
+       movl 8(%r14),%eax
+       movl %eax,8(%rbx)
+       movl 12(%r14),%eax
+       movl %eax,12(%rbx)
+.Lcb:
+       jmp *(%rbp)
+       .size callMemcpy, .-callMemcpy
+.section .note.GNU-stack,"",@progbits
+.ident "GHC 7.7.20121009"
diff --git a/tests/codeGen/should_gen_asm/memcpy-unroll-conprop.cmm 
b/tests/codeGen/should_gen_asm/memcpy-unroll-conprop.cmm
new file mode 100644
index 0000000..be4883d
--- /dev/null
+++ b/tests/codeGen/should_gen_asm/memcpy-unroll-conprop.cmm
@@ -0,0 +1,14 @@
+#include "Cmm.h"
+
+// Check that we propagate the constants into the branch
+callMemcpy (W_ dst, W_ src)
+{
+    W_ size;
+    W_ alig;
+    size = 16;
+    alig = 4;
+    if (dst != 0) {
+      prim %memcpy(dst, src, size, alig);
+    }
+    return ();
+}
diff --git a/tests/codeGen/should_gen_asm/memcpy-unroll.asm 
b/tests/codeGen/should_gen_asm/memcpy-unroll.asm
new file mode 100644
index 0000000..ffb27e7
--- /dev/null
+++ b/tests/codeGen/should_gen_asm/memcpy-unroll.asm
@@ -0,0 +1,18 @@
+.text
+       .align 8
+.globl callMemcpy
+.type callMemcpy, @object
+callMemcpy:
+.Lc3:
+       movl 0(%r14),%eax
+       movl %eax,0(%rbx)
+       movl 4(%r14),%eax
+       movl %eax,4(%rbx)
+       movl 8(%r14),%eax
+       movl %eax,8(%rbx)
+       movl 12(%r14),%eax
+       movl %eax,12(%rbx)
+       jmp *(%rbp)
+       .size callMemcpy, .-callMemcpy
+.section .note.GNU-stack,"",@progbits
+.ident "GHC 7.7.20121009"
diff --git a/tests/codeGen/should_gen_asm/memcpy-unroll.cmm 
b/tests/codeGen/should_gen_asm/memcpy-unroll.cmm
new file mode 100644
index 0000000..95656b4
--- /dev/null
+++ b/tests/codeGen/should_gen_asm/memcpy-unroll.cmm
@@ -0,0 +1,8 @@
+#include "Cmm.h"
+
+// Small memcpies should unroll
+callMemcpy (W_ dst, W_ src)
+{
+  prim %memcpy(dst, src, 16, 4);
+  return ();
+}
diff --git a/tests/codeGen/should_gen_asm/memcpy.asm 
b/tests/codeGen/should_gen_asm/memcpy.asm
new file mode 100644
index 0000000..1fb604f
--- /dev/null
+++ b/tests/codeGen/should_gen_asm/memcpy.asm
@@ -0,0 +1,9 @@
+callMemcpy:
+        movq  ; Move arguments into place
+        movq
+        movl
+        subq
+        movl
+        call memcpy
+        addq
+        jmp
diff --git a/tests/codeGen/should_gen_asm/memcpy.cmm 
b/tests/codeGen/should_gen_asm/memcpy.cmm
new file mode 100644
index 0000000..0ff1663
--- /dev/null
+++ b/tests/codeGen/should_gen_asm/memcpy.cmm
@@ -0,0 +1,8 @@
+#include "Cmm.h"
+
+// Large memcpy's should lower to calls.
+callMemcpy (W_ dst, W_ src)
+{
+  prim %memcpy(dst, src, 1024, 4);
+  return ();
+}



_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to