gitee.com/quant1x/num@v0.3.2/asm/c2goasm/assembly_test.go (about) 1 /* 2 * Minio Cloud Storage, (C) 2017 Minio, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "strings" 21 "testing" 22 ) 23 24 func TestAssemblyAlignedWithTableWithStackArgs(t *testing.T) { 25 26 epilogue := Epilogue{SetRbpInstr: true, StackSize: 64, AlignedStack: true, AlignValue: 16, VZeroUpper: false} 27 epilogue.Pops = append(epilogue.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 28 table := Table{Name: "LCDATA3"} 29 30 subroutine := Subroutine{name: "SimdSse2MedianFilterRhomb5x5", epilogue: epilogue, table: table} 31 arguments, returnValues := []string{}, []string{} 32 arguments = append(arguments, "src", "srcStride", "width", "height", "channelCount", "dst", "dstStride") 33 34 stack := NewStack(epilogue, len(arguments), 0) 35 36 lines := writeGoasmPrologue(subroutine, stack, arguments, returnValues) 37 lines = append(lines, writeGoasmEpilogue(subroutine, stack, arguments, returnValues)...) 38 39 alignedWithTable := `TEXT ·_SimdSse2MedianFilterRhomb5x5(SB), $96-56 40 41 MOVQ src+0(FP), DI 42 MOVQ srcStride+8(FP), SI 43 MOVQ width+16(FP), DX 44 MOVQ height+24(FP), CX 45 MOVQ channelCount+32(FP), R8 46 MOVQ dst+40(FP), R9 47 MOVQ dstStride+48(FP), R10 48 MOVQ SP, BP 49 ADDQ $16, SP 50 ANDQ $-16, SP 51 MOVQ BP, 72(SP) 52 MOVQ R10, 64(SP) 53 LEAQ LCDATA3<>(SB), BP 54 55 MOVQ 72(SP), SP 56 RET` 57 58 for i, l := range lines { 59 goldenLine := strings.Split(alignedWithTable, "\n")[i] 60 if strings.TrimSpace(l) != strings.TrimSpace(goldenLine) { 61 t.Errorf("TestAssemblyAlignedWithTableWithStackArgs(): \nexpected %s\ngot %s", goldenLine, l) 62 } 63 } 64 65 test := "mov r11, qword ptr [rbp + 16]" 66 67 result := fixRbpPlusLoad(test, StackArgs{Number: 1, OffsetToFirst: 16}, stack) 68 69 dstStrideMov := `mov r11, qword ptr 64[rsp] /* [rbp + 16] */` 70 if dstStrideMov != result { 71 t.Errorf("TestAssemblyAlignedWithTableWithStackArgs(): \nexpected %s\ngot %s", dstStrideMov, result) 72 } 73 } 74 75 func TestAssemblyUnalignedWithTableWithStackArgs(t *testing.T) { 76 77 epilogue := Epilogue{SetRbpInstr: true, StackSize: 8, AlignedStack: false, AlignValue: 0, VZeroUpper: false} 78 epilogue.Pops = append(epilogue.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 79 table := Table{Name: "LCDATA2"} 80 81 subroutine := Subroutine{name: "SimdSse2MedianFilterSquare3x3", epilogue: epilogue, table: table} 82 arguments, returnValues := []string{}, []string{} 83 arguments = append(arguments, "src", "srcStride", "width", "height", "channelCount", "dst", "dstStride") 84 85 stack := NewStack(epilogue, len(arguments), 0) 86 87 lines := writeGoasmPrologue(subroutine, stack, arguments, returnValues) 88 lines = append(lines, writeGoasmEpilogue(subroutine, stack, arguments, returnValues)...) 89 90 unalignedWithTable := `TEXT ·_SimdSse2MedianFilterSquare3x3(SB), $24-56 91 92 MOVQ src+0(FP), DI 93 MOVQ srcStride+8(FP), SI 94 MOVQ width+16(FP), DX 95 MOVQ height+24(FP), CX 96 MOVQ channelCount+32(FP), R8 97 MOVQ dst+40(FP), R9 98 MOVQ dstStride+48(FP), R10 99 ADDQ $8, SP 100 MOVQ R10, 8(SP) 101 LEAQ LCDATA2<>(SB), BP 102 103 SUBQ $8, SP 104 RET` 105 106 for i, l := range lines { 107 goldenLine := strings.Split(unalignedWithTable, "\n")[i] 108 if strings.TrimSpace(l) != strings.TrimSpace(goldenLine) { 109 t.Errorf("TestAssemblyUnalignedWithTableWithStackArgs(): \nexpected %s\ngot %s", goldenLine, l) 110 } 111 } 112 113 test := "mov rax, qword [rbp + 16]" 114 115 result := fixRbpPlusLoad(test, StackArgs{Number: 1, OffsetToFirst: 16}, stack) 116 117 dstStrideMov := `mov rax, qword 8[rsp] /* [rbp + 16] */` 118 if dstStrideMov != result { 119 t.Errorf("TestAssemblyUnalignedWithTableWithStackArgs(): \nexpected %s\ngot %s", dstStrideMov, result) 120 121 } 122 } 123 124 func TestAssemblyUnalignedWithTableWithStackArgsWithStackZeroSize(t *testing.T) { 125 126 epilogue := Epilogue{SetRbpInstr: true, StackSize: 0, AlignedStack: false, AlignValue: 0, VZeroUpper: false} 127 epilogue.Pops = append(epilogue.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 128 table := Table{Name: "LCDATA1"} 129 130 subroutine := Subroutine{name: "SimdSse2MedianFilterRhomb3x3", epilogue: epilogue, table: table} 131 arguments, returnValues := []string{}, []string{} 132 arguments = append(arguments, "src", "srcStride", "width", "height", "channelCount", "dst", "dstStride") 133 134 stack := NewStack(epilogue, len(arguments), 0) 135 136 lines := writeGoasmPrologue(subroutine, stack, arguments, returnValues) 137 lines = append(lines, writeGoasmEpilogue(subroutine, stack, arguments, returnValues)...) 138 139 unalignedWithTableWithStackZeroSize := `TEXT ·_SimdSse2MedianFilterRhomb3x3(SB), $16-56 140 141 MOVQ src+0(FP), DI 142 MOVQ srcStride+8(FP), SI 143 MOVQ width+16(FP), DX 144 MOVQ height+24(FP), CX 145 MOVQ channelCount+32(FP), R8 146 MOVQ dst+40(FP), R9 147 MOVQ dstStride+48(FP), R10 148 ADDQ $8, SP 149 MOVQ R10, 0(SP) 150 LEAQ LCDATA1<>(SB), BP 151 152 SUBQ $8, SP 153 RET` 154 155 for i, l := range lines { 156 goldenLine := strings.Split(unalignedWithTableWithStackZeroSize, "\n")[i] 157 if strings.TrimSpace(l) != strings.TrimSpace(goldenLine) { 158 t.Errorf("TestAssemblyUnalignedWithTableWithStackArgsWithStackZeroSize(): \nexpected %s\ngot %s", goldenLine, l) 159 } 160 } 161 162 test := "mov rax, qword [rbp + 16]" 163 164 result := fixRbpPlusLoad(test, StackArgs{Number: 1, OffsetToFirst: 16}, stack) 165 166 dstStrideMov := `mov rax, qword 0[rsp] /* [rbp + 16] */` 167 if dstStrideMov != result { 168 t.Errorf("TestAssemblyUnalignedWithTableWithStackArgsWithStackZeroSize(): \nexpected %s\ngot %s", dstStrideMov, result) 169 170 } 171 } 172 173 func TestStripComments(t *testing.T) { 174 175 stripped, notskip := stripComments(` mov qword ptr [rsp + 144], r9 ## 8-byte Spill`) 176 expected := ` mov qword ptr [rsp + 144], r9` 177 if stripped != expected || notskip { 178 t.Errorf("TestStripComments(): \nexpected %s\ngot %s", expected, stripped) 179 } 180 181 stripped2, notskip2 := stripComments(` movdqa xmm3, xmmword ptr [rip + .LCPI2_10] # xmm3 = [59507,8192,59507,8192,59507,8192,59507,8192]`) 182 expected = ` movdqa xmm3, xmmword ptr [rip + .LCPI2_10]` 183 if stripped2 != expected || notskip2 { 184 t.Errorf("TestStripComments(): \nexpected %s\ngot %s", expected, stripped2) 185 } 186 187 empty, skip := stripComments(` ## =>This Loop Header: Depth=1`) 188 expected = `` 189 if empty != expected || !skip { 190 t.Errorf("TestStripComments(): \nexpected %s\ngot %s", expected, empty) 191 } 192 193 }