gitee.com/quant1x/num@v0.3.2/asm/c2goasm/epilogue_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 equalString(a, b []string) bool { 25 26 if len(a) != len(b) { 27 return false 28 } 29 30 for i := range a { 31 if a[i] != b[i] { 32 return false 33 } 34 } 35 return true 36 } 37 38 func testEpilogue(t *testing.T, prologue, epilogue string, expected Epilogue) { 39 src := strings.Split(epilogue, "\n") 40 stack := extractEpilogueInfo(src, 0, len(src)) 41 42 for _, line := range strings.Split(prologue, "\n") { 43 isPrologue := stack.isPrologueInstruction(line) 44 if !isPrologue { 45 t.Errorf("testEpilogue(): \nexpected true\ngot %#v", isPrologue) 46 } 47 } 48 49 if stack.StackSize != expected.StackSize || stack.AlignedStack != expected.AlignedStack || 50 stack.VZeroUpper != expected.VZeroUpper || !equalString(stack.Pops, expected.Pops) || 51 stack.SetRbpInstr != expected.SetRbpInstr { 52 t.Errorf("testEpilogue(): \nexpected %#v\ngot %#v", expected, stack) 53 } 54 } 55 56 func TestEpilogues(t *testing.T) { 57 58 asmPrologue1 := ` push rbp 59 mov rbp, rsp` 60 61 epilogue1 := Epilogue{SetRbpInstr: true, VZeroUpper: true} 62 epilogue1.Pops = append(epilogue1.Pops, "rbp") 63 64 asmEpilogue1 := ` pop rbp 65 vzeroupper 66 ret` 67 68 testEpilogue(t, asmPrologue1, asmEpilogue1, epilogue1) 69 70 /***********************************************************************************/ 71 72 asmPrologue2 := ` push rbp 73 mov rbp, rsp 74 push r15 75 push r14 76 push r13 77 push r12 78 push rbx 79 and rsp, -32 80 sub rsp, 864` 81 82 epilogue2 := Epilogue{SetRbpInstr: true, StackSize: 864, AlignedStack: true, AlignValue: 32} 83 epilogue2.Pops = append(epilogue2.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 84 85 asmEpilogue2 := ` lea rsp, [rbp - 40] 86 pop rbx 87 pop r12 88 pop r13 89 pop r14 90 pop r15 91 pop rbp` 92 93 testEpilogue(t, asmPrologue2, asmEpilogue2, epilogue2) 94 95 /***********************************************************************************/ 96 97 asmPrologue3 := `push rbp 98 mov rbp, rsp 99 push r15 100 push r14 101 push r13 102 push r12 103 push rbx` 104 105 epilogue3 := Epilogue{SetRbpInstr: true} 106 epilogue3.Pops = append(epilogue3.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 107 108 asmEpilogue3 := ` pop rbx 109 pop r12 110 pop r13 111 pop r14 112 pop r15 113 pop rbp` 114 115 testEpilogue(t, asmPrologue3, asmEpilogue3, epilogue3) 116 117 /***********************************************************************************/ 118 119 asmPrologue4 := `push rbp 120 mov rbp, rsp 121 push r15 122 push r14 123 push r13 124 push r12 125 push rbx 126 sub rsp, 152` 127 128 epilogue4 := Epilogue{SetRbpInstr: true, StackSize: 152} 129 epilogue4.Pops = append(epilogue4.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 130 131 asmEpilogue4 := ` add rsp, 152 132 pop rbx 133 pop r12 134 pop r13 135 pop r14 136 pop r15 137 pop rbp` 138 139 testEpilogue(t, asmPrologue4, asmEpilogue4, epilogue4) 140 141 /***********************************************************************************/ 142 143 asmPrologue5 := `push rbp 144 mov rbp, rsp 145 push r15 146 push r14 147 push r13 148 push r12 149 push rbx 150 and rsp, -32 151 sub rsp, 192` 152 153 epilogue5 := Epilogue{SetRbpInstr: true, StackSize: 192, AlignedStack: true, AlignValue: 32, VZeroUpper: true} 154 epilogue5.Pops = append(epilogue5.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 155 156 asmEpilogue5 := ` lea rsp, [rbp - 40] 157 pop rbx 158 pop r12 159 pop r13 160 pop r14 161 pop r15 162 pop rbp 163 vzeroupper 164 ret` 165 166 testEpilogue(t, asmPrologue5, asmEpilogue5, epilogue5) 167 168 /***********************************************************************************/ 169 170 asmPrologue6 := `push rbp 171 mov rbp, rsp 172 push r15 173 push r14 174 push r13 175 push r12 176 push rbx 177 push rax` 178 179 epilogue6 := Epilogue{SetRbpInstr: true, VZeroUpper: true} 180 epilogue6.Pops = append(epilogue6.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 181 182 // `add rsp, 8` counters the additional `push rax` (there are 7 pushes and 6 pops) 183 asmEpilogue6 := ` add rsp, 8 184 pop rbx 185 pop r12 186 pop r13 187 pop r14 188 pop r15 189 pop rbp 190 vzeroupper 191 ret` 192 193 testEpilogue(t, asmPrologue6, asmEpilogue6, epilogue6) 194 195 asmPrologue7 := ` push rbp 196 mov rbp, rsp 197 push r15 198 push r14 199 push r13 200 push r12 201 push rbx 202 and rsp, -8 203 push rax` 204 205 asmEpilogue7 := ` lea rsp, [rbp - 40] 206 pop rbx 207 pop r12 208 pop r13 209 pop r14 210 pop r15 211 pop rbp 212 ret` 213 214 epilogue7 := Epilogue{SetRbpInstr: true, VZeroUpper: false, StackSize: 8} 215 epilogue7.Pops = append(epilogue7.Pops, "rbp", "r15", "r14", "r13", "r12", "rbx") 216 217 testEpilogue(t, asmPrologue7, asmEpilogue7, epilogue7) 218 219 asmPrologue8 := `push rbp 220 mov rbp, rsp 221 and rsp, -8` 222 223 asmEpilogue8 := `mov rsp, rbp 224 pop rbp 225 ret` 226 227 epilogue8 := Epilogue{SetRbpInstr: true, VZeroUpper: false, StackSize: 0} 228 epilogue8.Pops = append(epilogue8.Pops, "rbp") 229 230 testEpilogue(t, asmPrologue8, asmEpilogue8, epilogue8) 231 232 }