gitee.com/quant1x/gox@v1.7.6/num/asm/max.go (about) 1 package main 2 3 import ( 4 . "github.com/mmcloughlin/avo/build" 5 . "github.com/mmcloughlin/avo/operand" 6 . "github.com/mmcloughlin/avo/reg" 7 ) 8 9 func genMax_F64() { 10 data := GLOBL("dataMaxF64", RODATA|NOPTR) 11 DATA(0, U64(0xffefffffffffffff)) 12 13 TEXT("Max_AVX2_F64", NOSPLIT, "func(x []float64) float64") 14 Pragma("noescape") 15 Load(Param("x").Base(), RDI) 16 Load(Param("x").Len(), RSI) 17 18 TESTQ(RSI, RSI) 19 JE(LabelRef("empty")) 20 CMPQ(RSI, Imm(16)) 21 JAE(LabelRef("loop")) 22 VMOVSD(data, X0) 23 XORL(EAX, EAX) 24 JMP(LabelRef("collect")) 25 26 Label("empty") 27 { 28 VMOVSD(data, X0) 29 Store(X0, ReturnIndex(0)) 30 RET() 31 } 32 33 Label("loop") 34 { 35 MOVQ(RSI, RAX) 36 ANDQ(I32(-16), RAX) 37 LEAQ(Mem{Base: RAX}.Offset(-16), RCX) 38 MOVQ(RCX, R8) 39 SHRQ(Imm(4), R8) 40 ADDQ(Imm(1), R8) 41 TESTQ(RCX, RCX) 42 JE(LabelRef("setmin")) 43 MOVQ(R8, RCX) 44 ANDQ(I32(-2), RCX) 45 VBROADCASTSD(data, Y0) 46 XORL(EDX, EDX) 47 VMOVAPD(Y0, Y1) 48 VMOVAPD(Y0, Y2) 49 VMOVAPD(Y0, Y3) 50 } 51 52 Label("body") 53 { 54 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8), Y0, Y0) 55 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(32), Y1, Y1) 56 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(64), Y2, Y2) 57 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(96), Y3, Y3) 58 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(128), Y0, Y0) 59 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(160), Y1, Y1) 60 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(192), Y2, Y2) 61 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(224), Y3, Y3) 62 ADDQ(I32(32), RDX) 63 ADDQ(I32(-2), RCX) 64 JNE(LabelRef("body")) 65 TESTB(Imm(1), R8B) 66 JE(LabelRef("combinevectors")) 67 } 68 69 Label("tail") 70 { 71 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8), Y0, Y0) 72 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(32), Y1, Y1) 73 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(64), Y1, Y1) 74 VMAXPD(Mem{Base: RDI}.Idx(RDX, 8).Offset(96), Y1, Y1) 75 } 76 77 Label("combinevectors") 78 { 79 VMAXPD(Y3, Y0, Y0) 80 VMAXPD(Y2, Y1, Y1) 81 VMAXPD(Y0, Y1, Y0) 82 VEXTRACTF128(Imm(1), Y0, X1) 83 VMAXPD(X1, X0, X0) 84 VPERMILPD(Imm(1), X0, X1) 85 VMAXSD(X1, X0, X0) 86 CMPQ(RAX, RSI) 87 JE(LabelRef("return")) 88 } 89 90 Label("collect") 91 { 92 VMAXSD(Mem{Base: RDI}.Idx(RAX, 8), X0, X0) 93 ADDQ(Imm(1), RAX) 94 CMPQ(RSI, RAX) 95 JNE(LabelRef("collect")) 96 } 97 98 Label("return") 99 { 100 VZEROUPPER() 101 Store(X0, ReturnIndex(0)) 102 RET() 103 } 104 105 Label("setmin") 106 { 107 VBROADCASTSD(data, Y0) 108 XORL(EDX, EDX) 109 VMOVAPD(Y0, Y1) 110 VMOVAPD(Y0, Y2) 111 VMOVAPD(Y0, Y3) 112 TESTB(Imm(1), R8B) 113 JNE(LabelRef("tail")) 114 JMP(LabelRef("combinevectors")) 115 } 116 } 117 118 func genMax_F32() { 119 data := GLOBL("dataMaxF32", RODATA|NOPTR) 120 DATA(0, U32(0xff7fffff)) 121 122 TEXT("Max_AVX2_F32", NOSPLIT, "func(x []float32) float32") 123 Pragma("noescape") 124 Load(Param("x").Base(), RDI) 125 Load(Param("x").Len(), RSI) 126 127 TESTQ(RSI, RSI) 128 JE(LabelRef("empty")) 129 CMPQ(RSI, Imm(32)) 130 JAE(LabelRef("loop")) 131 VMOVSS(data, X0) 132 XORL(EAX, EAX) 133 JMP(LabelRef("collect")) 134 135 Label("empty") 136 { 137 VMOVSS(data, X0) 138 Store(X0, ReturnIndex(0)) 139 RET() 140 } 141 142 Label("loop") 143 { 144 MOVQ(RSI, RAX) 145 ANDQ(I32(-32), RAX) 146 LEAQ(Mem{Base: RAX}.Offset(-32), RCX) 147 MOVQ(RCX, R8) 148 SHRQ(Imm(5), R8) 149 ADDQ(Imm(1), R8) 150 TESTQ(RCX, RCX) 151 JE(LabelRef("setmin")) 152 MOVQ(R8, RCX) 153 ANDQ(I32(-2), RCX) 154 VBROADCASTSS(data, Y0) 155 XORL(EDX, EDX) 156 VMOVAPD(Y0, Y1) 157 VMOVAPD(Y0, Y2) 158 VMOVAPD(Y0, Y3) 159 } 160 161 Label("body") 162 { 163 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4), Y0, Y0) 164 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(32), Y1, Y1) 165 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(64), Y2, Y2) 166 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(96), Y3, Y3) 167 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(128), Y0, Y0) 168 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(160), Y1, Y1) 169 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(192), Y2, Y2) 170 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(224), Y3, Y3) 171 ADDQ(I32(64), RDX) 172 ADDQ(I32(-2), RCX) 173 JNE(LabelRef("body")) 174 TESTB(Imm(1), R8B) 175 JE(LabelRef("combinevectors")) 176 } 177 178 Label("tail") 179 { 180 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4), Y0, Y0) 181 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(32), Y1, Y1) 182 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(64), Y1, Y1) 183 VMAXPS(Mem{Base: RDI}.Idx(RDX, 4).Offset(96), Y1, Y1) 184 } 185 186 Label("combinevectors") 187 { 188 VMAXPS(Y3, Y0, Y0) 189 VMAXPS(Y2, Y1, Y1) 190 VMAXPS(Y0, Y1, Y0) 191 VEXTRACTF128(Imm(1), Y0, X1) 192 VMAXPS(X1, X0, X0) 193 VPERMILPD(Imm(1), X0, X1) 194 VMAXPS(X1, X0, X0) 195 VMOVSHDUP(X0, X1) 196 VMAXSS(X1, X0, X0) 197 CMPQ(RAX, RSI) 198 JE(LabelRef("return")) 199 } 200 201 Label("collect") 202 { 203 VMAXSS(Mem{Base: RDI}.Idx(RAX, 4), X0, X0) 204 ADDQ(Imm(1), RAX) 205 CMPQ(RSI, RAX) 206 JNE(LabelRef("collect")) 207 } 208 209 Label("return") 210 { 211 VZEROUPPER() 212 Store(X0, ReturnIndex(0)) 213 RET() 214 } 215 216 Label("setmin") 217 { 218 VBROADCASTSS(data, Y0) 219 XORL(EDX, EDX) 220 VMOVAPS(Y0, Y1) 221 VMOVAPS(Y0, Y2) 222 VMOVAPS(Y0, Y3) 223 TESTB(Imm(1), R8B) 224 JNE(LabelRef("tail")) 225 JMP(LabelRef("combinevectors")) 226 } 227 } 228 229 func genMaximum_F64() { 230 TEXT("Maximum_AVX2_F64", NOSPLIT, "func(x, y []float64)") 231 Pragma("noescape") 232 Load(Param("x").Base(), RDI) 233 Load(Param("y").Base(), RSI) 234 Load(Param("x").Len(), RDX) 235 236 TESTQ(RDX, RDX) 237 JE(LabelRef("return")) 238 CMPQ(RDX, Imm(16)) 239 JAE(LabelRef("loop")) 240 XORL(EAX, EAX) 241 JMP(LabelRef("tailbody")) 242 243 Label("loop") 244 { 245 MOVQ(RDX, RAX) 246 ANDQ(I32(-16), RAX) 247 LEAQ(Mem{Base: RDI}.Offset(96), R8) 248 XORL(ECX, ECX) 249 } 250 251 Label("body") 252 { 253 VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8), Y0) 254 VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(32), Y1) 255 VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(64), Y2) 256 VMOVUPD(Mem{Base: RSI}.Idx(RCX, 8).Offset(96), Y3) 257 VMOVUPD(Mem{Base: R8}.Idx(RCX, 8).Offset(-96), Y4) 258 VMOVUPD(Mem{Base: R8}.Idx(RCX, 8).Offset(-64), Y5) 259 VMOVUPD(Mem{Base: R8}.Idx(RCX, 8).Offset(-32), Y6) 260 VMOVUPD(Mem{Base: R8}.Idx(RCX, 8), Y7) 261 VCMPPD(Imm(1), Y0, Y4, Y4) 262 VMASKMOVPD(Y0, Y4, Mem{Base: R8}.Idx(RCX, 8).Offset(-96)) 263 VCMPPD(Imm(1), Y1, Y5, Y0) 264 VMASKMOVPD(Y1, Y0, Mem{Base: R8}.Idx(RCX, 8).Offset(-64)) 265 VCMPPD(Imm(1), Y2, Y6, Y0) 266 VMASKMOVPD(Y2, Y0, Mem{Base: R8}.Idx(RCX, 8).Offset(-32)) 267 VCMPPD(Imm(1), Y3, Y7, Y0) 268 VMASKMOVPD(Y3, Y0, Mem{Base: R8}.Idx(RCX, 8)) 269 ADDQ(Imm(16), RCX) 270 CMPQ(RCX, RAX) 271 JNE(LabelRef("body")) 272 CMPQ(RDX, RAX) 273 JNE(LabelRef("tailbody")) 274 } 275 276 Label("return") 277 { 278 VZEROUPPER() 279 RET() 280 } 281 282 Label("tail") 283 { 284 ADDQ(Imm(1), RAX) 285 CMPQ(RAX, RDX) 286 JE(LabelRef("return")) 287 } 288 289 Label("tailbody") 290 { 291 VMOVSD(Mem{Base: RSI}.Idx(RAX, 8), X0) 292 VUCOMISD(Mem{Base: RDI}.Idx(RAX, 8), X0) 293 JBE(LabelRef("tail")) 294 VMOVSD(X0, Mem{Base: RDI}.Idx(RAX, 8)) 295 JMP(LabelRef("tail")) 296 } 297 } 298 299 func genMaximum_F32() { 300 TEXT("Maximum_AVX2_F32", NOSPLIT, "func(x, y []float32)") 301 Pragma("noescape") 302 Load(Param("x").Base(), RDI) 303 Load(Param("y").Base(), RSI) 304 Load(Param("x").Len(), RDX) 305 306 TESTQ(RDX, RDX) 307 JE(LabelRef("return")) 308 CMPQ(RDX, Imm(32)) 309 JAE(LabelRef("loop")) 310 XORL(EAX, EAX) 311 JMP(LabelRef("tailbody")) 312 313 Label("loop") 314 { 315 MOVQ(RDX, RAX) 316 ANDQ(I32(-32), RAX) 317 LEAQ(Mem{Base: RDI}.Offset(96), R8) 318 XORL(ECX, ECX) 319 } 320 321 Label("body") 322 { 323 VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4), Y0) 324 VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(32), Y1) 325 VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(64), Y2) 326 VMOVUPS(Mem{Base: RSI}.Idx(RCX, 4).Offset(96), Y3) 327 VMOVUPS(Mem{Base: R8}.Idx(RCX, 4).Offset(-96), Y4) 328 VMOVUPS(Mem{Base: R8}.Idx(RCX, 4).Offset(-64), Y5) 329 VMOVUPS(Mem{Base: R8}.Idx(RCX, 4).Offset(-32), Y6) 330 VMOVUPS(Mem{Base: R8}.Idx(RCX, 4), Y7) 331 VCMPPS(Imm(1), Y0, Y4, Y4) 332 VMASKMOVPS(Y0, Y4, Mem{Base: R8}.Idx(RCX, 4).Offset(-96)) 333 VCMPPS(Imm(1), Y1, Y5, Y0) 334 VMASKMOVPS(Y1, Y0, Mem{Base: R8}.Idx(RCX, 4).Offset(-64)) 335 VCMPPS(Imm(1), Y2, Y6, Y0) 336 VMASKMOVPS(Y2, Y0, Mem{Base: R8}.Idx(RCX, 4).Offset(-32)) 337 VCMPPS(Imm(1), Y3, Y7, Y0) 338 VMASKMOVPS(Y3, Y0, Mem{Base: R8}.Idx(RCX, 4)) 339 ADDQ(Imm(32), RCX) 340 CMPQ(RCX, RAX) 341 JNE(LabelRef("body")) 342 CMPQ(RDX, RAX) 343 JNE(LabelRef("tailbody")) 344 } 345 346 Label("return") 347 { 348 VZEROUPPER() 349 RET() 350 } 351 352 Label("tail") 353 { 354 ADDQ(Imm(1), RAX) 355 CMPQ(RAX, RDX) 356 JE(LabelRef("return")) 357 } 358 359 Label("tailbody") 360 { 361 VMOVSS(Mem{Base: RSI}.Idx(RAX, 4), X0) 362 VUCOMISS(Mem{Base: RDI}.Idx(RAX, 4), X0) 363 JBE(LabelRef("tail")) 364 VMOVSS(X0, Mem{Base: RDI}.Idx(RAX, 4)) 365 JMP(LabelRef("tail")) 366 } 367 } 368 369 func genMaximumNumber_F64() { 370 TEXT("MaximumNumber_AVX2_F64", NOSPLIT, "func(x []float64, a float64)") 371 Pragma("noescape") 372 Load(Param("x").Base(), RDI) 373 Load(Param("a"), X0) 374 Load(Param("x").Len(), RSI) 375 376 TESTQ(RSI, RSI) 377 JE(LabelRef("return")) 378 CMPQ(RSI, Imm(16)) 379 JAE(LabelRef("loop")) 380 XORL(EAX, EAX) 381 JMP(LabelRef("tailbody")) 382 383 Label("loop") 384 { 385 MOVQ(RSI, RAX) 386 ANDQ(I32(-16), RAX) 387 VBROADCASTSD(X0, Y1) 388 LEAQ(Mem{Base: RDI}.Offset(96), RCX) 389 XORL(EDX, EDX) 390 } 391 392 Label("body") 393 { 394 VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8).Offset(-96), Y2) 395 VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8).Offset(-64), Y3) 396 VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8).Offset(-32), Y4) 397 VMOVUPD(Mem{Base: RCX}.Idx(RDX, 8), Y5) 398 VCMPPD(Imm(1), Y1, Y2, Y2) 399 VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8).Offset(-96)) 400 VCMPPD(Imm(1), Y1, Y3, Y2) 401 VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8).Offset(-64)) 402 VCMPPD(Imm(1), Y1, Y4, Y2) 403 VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8).Offset(-32)) 404 VCMPPD(Imm(1), Y1, Y5, Y2) 405 VMASKMOVPD(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 8)) 406 ADDQ(Imm(16), RDX) 407 CMPQ(RAX, RDX) 408 JNE(LabelRef("body")) 409 CMPQ(RAX, RSI) 410 JNE(LabelRef("tailbody")) 411 } 412 413 Label("return") 414 { 415 VZEROUPPER() 416 RET() 417 } 418 419 Label("tail") 420 { 421 ADDQ(Imm(1), RAX) 422 CMPQ(RSI, RAX) 423 JE(LabelRef("return")) 424 } 425 426 Label("tailbody") 427 { 428 VUCOMISD(Mem{Base: RDI}.Idx(RAX, 8), X0) 429 JBE(LabelRef("tail")) 430 VMOVSD(X0, Mem{Base: RDI}.Idx(RAX, 8)) 431 JMP(LabelRef("tail")) 432 } 433 } 434 435 func genMaximumNumber_F32() { 436 TEXT("MaximumNumber_AVX2_F32", NOSPLIT, "func(x []float32, a float32)") 437 Pragma("noescape") 438 Load(Param("x").Base(), RDI) 439 Load(Param("a"), X0) 440 Load(Param("x").Len(), RSI) 441 442 TESTQ(RSI, RSI) 443 JE(LabelRef("return")) 444 CMPQ(RSI, Imm(32)) 445 JAE(LabelRef("loop")) 446 XORL(EAX, EAX) 447 JMP(LabelRef("tailbody")) 448 449 Label("loop") 450 { 451 MOVQ(RSI, RAX) 452 ANDQ(I32(-32), RAX) 453 VBROADCASTSS(X0, Y1) 454 LEAQ(Mem{Base: RDI}.Offset(96), RCX) 455 XORL(EDX, EDX) 456 } 457 458 Label("body") 459 { 460 VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4).Offset(-96), Y2) 461 VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4).Offset(-64), Y3) 462 VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4).Offset(-32), Y4) 463 VMOVUPS(Mem{Base: RCX}.Idx(RDX, 4), Y5) 464 VCMPPS(Imm(1), Y1, Y2, Y2) 465 VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4).Offset(-96)) 466 VCMPPS(Imm(1), Y1, Y3, Y2) 467 VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4).Offset(-64)) 468 VCMPPS(Imm(1), Y1, Y4, Y2) 469 VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4).Offset(-32)) 470 VCMPPS(Imm(1), Y1, Y5, Y2) 471 VMASKMOVPS(Y1, Y2, Mem{Base: RCX}.Idx(RDX, 4)) 472 ADDQ(Imm(32), RDX) 473 CMPQ(RAX, RDX) 474 JNE(LabelRef("body")) 475 CMPQ(RAX, RSI) 476 JNE(LabelRef("tailbody")) 477 } 478 479 Label("return") 480 { 481 VZEROUPPER() 482 RET() 483 } 484 485 Label("tail") 486 { 487 ADDQ(Imm(1), RAX) 488 CMPQ(RSI, RAX) 489 JE(LabelRef("return")) 490 } 491 492 Label("tailbody") 493 { 494 VUCOMISS(Mem{Base: RDI}.Idx(RAX, 4), X0) 495 JBE(LabelRef("tail")) 496 VMOVSS(X0, Mem{Base: RDI}.Idx(RAX, 4)) 497 JMP(LabelRef("tail")) 498 } 499 }