@@ -18,6 +18,49 @@ import (
18
18
"testing"
19
19
)
20
20
21
+ // This file contains code generation tests.
22
+ //
23
+ // Each test is defined in a variable of type asmTest. Tests are
24
+ // architecture-specific, and they are grouped in arrays of tests, one
25
+ // for each architecture.
26
+ //
27
+ // Each asmTest consists in a function to be compiled and an array of
28
+ // regexps that will be matched to the generated assembly. For
29
+ // example, the following amd64 test
30
+ //
31
+ // {
32
+ // `
33
+ // func f0(x int) int {
34
+ // return x * 64
35
+ // }
36
+ // `,
37
+ // []string{"\tSHLQ\t[$]6,"},
38
+ // }
39
+ //
40
+ // verifies that the code the compiler generates for a multiplication
41
+ // by 64 contains a 'SHLQ' instruction.
42
+ //
43
+ // Since all the tests for a given architecture are dumped in the same
44
+ // file, the function names must be unique. As a workaround for this
45
+ // restriction, the test harness supports the use of a '$' placeholder
46
+ // for function names. The func f0 above can be also written as
47
+ //
48
+ // {
49
+ // `
50
+ // func $(x int) int {
51
+ // return x * 64
52
+ // }
53
+ // `,
54
+ // []string{"\tSHLQ\t[$]6,"},
55
+ // }
56
+ //
57
+ // Each '$'-function will be given a unique name of form f<N>_<arch>,
58
+ // where <N> is the test index in the test array, and <arch> is the
59
+ // test's architecture.
60
+ //
61
+ // It is allowed to mix named and unnamed functions in the same test
62
+ // array; the named function will retain their original names.
63
+
21
64
// TestAssembly checks to make sure the assembly generated for
22
65
// functions contains certain expected instructions.
23
66
func TestAssembly (t * testing.T ) {
@@ -41,8 +84,13 @@ func TestAssembly(t *testing.T) {
41
84
42
85
asm := ats .compileToAsm (tt , dir )
43
86
44
- for _ , at := range ats .tests {
45
- funcName := nameRegexp .FindString (at .function )[len ("func " ):]
87
+ for i , at := range ats .tests {
88
+ var funcName string
89
+ if strings .Contains (at .function , "func $" ) {
90
+ funcName = fmt .Sprintf ("f%d_%s" , i , ats .arch )
91
+ } else {
92
+ funcName = nameRegexp .FindString (at .function )[len ("func " ):]
93
+ }
46
94
fa := funcAsm (tt , asm , funcName )
47
95
if fa != "" {
48
96
at .verifyAsm (tt , fa )
@@ -74,8 +122,7 @@ func funcAsm(t *testing.T, asm string, funcName string) string {
74
122
}
75
123
76
124
type asmTest struct {
77
- // function to compile, must be named fX,
78
- // where X is this test's index in asmTests.tests.
125
+ // function to compile
79
126
function string
80
127
// regexps that must match the generated assembly
81
128
regexps []string
@@ -103,8 +150,9 @@ func (ats *asmTests) generateCode() []byte {
103
150
fmt .Fprintf (& buf , "import %q\n " , s )
104
151
}
105
152
106
- for _ , t := range ats .tests {
107
- fmt .Fprintln (& buf , t .function )
153
+ for i , t := range ats .tests {
154
+ function := strings .Replace (t .function , "func $" , fmt .Sprintf ("func f%d_%s" , i , ats .arch ), 1 )
155
+ fmt .Fprintln (& buf , function )
108
156
}
109
157
110
158
return buf .Bytes ()
@@ -358,7 +406,7 @@ var linuxAMD64Tests = []*asmTest{
358
406
type T1 struct {
359
407
a, b, c int
360
408
}
361
- func f18 (t *T1) {
409
+ func $ (t *T1) {
362
410
*t = T1{}
363
411
}
364
412
` ,
@@ -951,17 +999,18 @@ var linux386Tests = []*asmTest{
951
999
` ,
952
1000
[]string {"\t MOVL\t \\ (.*\\ )\\ (.*\\ *1\\ )," },
953
1001
},
1002
+
954
1003
// multiplication merging tests
955
1004
{
956
1005
`
957
- func mul1 (n int) int {
1006
+ func $ (n int) int {
958
1007
return 9*n + 14*n
959
1008
}` ,
960
1009
[]string {"\t IMULL\t [$]23" }, // 23*n
961
1010
},
962
1011
{
963
1012
`
964
- func mul2 (a, n int) int {
1013
+ func $ (a, n int) int {
965
1014
return 19*a + a*n
966
1015
}` ,
967
1016
[]string {"\t ADDL\t [$]19" , "\t IMULL" }, // (n+19)*a
0 commit comments