| 
									
										
										
										
											2018-03-08 10:57:10 +01:00
										 |  |  | // asmcheck | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Copyright 2018 The Go Authors. All rights reserved. | 
					
						
							|  |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  | // license that can be found in the LICENSE file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package codegen | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This file contains codegen tests related to arithmetic | 
					
						
							| 
									
										
										
										
											2018-03-15 11:15:22 +01:00
										 |  |  | // simplifications and optimizations on integer types. | 
					
						
							|  |  |  | // For codegen tests on float types, see floats.go. | 
					
						
							| 
									
										
										
										
											2018-03-08 10:57:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-15 09:31:39 +00:00
										 |  |  | // ----------------- // | 
					
						
							|  |  |  | //    Subtraction    // | 
					
						
							|  |  |  | // ----------------- // | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-06 13:13:48 +00:00
										 |  |  | var ef int | 
					
						
							| 
									
										
										
										
											2019-03-13 13:52:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-06 13:13:48 +00:00
										 |  |  | func SubMem(arr []int, b, c, d int) int { | 
					
						
							| 
									
										
										
										
											2018-04-29 10:42:14 +00:00
										 |  |  | 	// 386:`SUBL\s[A-Z]+,\s8\([A-Z]+\)` | 
					
						
							| 
									
										
										
										
											2018-06-29 02:11:53 +00:00
										 |  |  | 	// amd64:`SUBQ\s[A-Z]+,\s16\([A-Z]+\)` | 
					
						
							| 
									
										
										
										
											2018-04-29 10:42:14 +00:00
										 |  |  | 	arr[2] -= b | 
					
						
							|  |  |  | 	// 386:`SUBL\s[A-Z]+,\s12\([A-Z]+\)` | 
					
						
							| 
									
										
										
										
											2018-06-29 02:11:53 +00:00
										 |  |  | 	// amd64:`SUBQ\s[A-Z]+,\s24\([A-Z]+\)` | 
					
						
							| 
									
										
										
										
											2018-04-29 10:42:14 +00:00
										 |  |  | 	arr[3] -= b | 
					
						
							| 
									
										
										
										
											2018-06-26 02:58:54 +00:00
										 |  |  | 	// 386:`DECL\s16\([A-Z]+\)` | 
					
						
							|  |  |  | 	arr[4]-- | 
					
						
							|  |  |  | 	// 386:`ADDL\s[$]-20,\s20\([A-Z]+\)` | 
					
						
							|  |  |  | 	arr[5] -= 20 | 
					
						
							| 
									
										
										
										
											2020-03-24 16:46:49 +00:00
										 |  |  | 	// 386:`SUBL\s\([A-Z]+\)\([A-Z]+\*4\),\s[A-Z]+` | 
					
						
							| 
									
										
										
										
											2018-10-06 13:13:48 +00:00
										 |  |  | 	ef -= arr[b] | 
					
						
							| 
									
										
										
										
											2020-03-24 16:46:49 +00:00
										 |  |  | 	// 386:`SUBL\s[A-Z]+,\s\([A-Z]+\)\([A-Z]+\*4\)` | 
					
						
							| 
									
										
										
										
											2018-10-06 13:13:48 +00:00
										 |  |  | 	arr[c] -= b | 
					
						
							| 
									
										
										
										
											2020-03-24 16:46:49 +00:00
										 |  |  | 	// 386:`ADDL\s[$]-15,\s\([A-Z]+\)\([A-Z]+\*4\)` | 
					
						
							| 
									
										
										
										
											2018-10-06 13:13:48 +00:00
										 |  |  | 	arr[d] -= 15 | 
					
						
							| 
									
										
										
										
											2020-03-24 16:46:49 +00:00
										 |  |  | 	// 386:`DECL\s\([A-Z]+\)\([A-Z]+\*4\)` | 
					
						
							| 
									
										
										
										
											2018-10-09 11:01:34 +00:00
										 |  |  | 	arr[b]-- | 
					
						
							| 
									
										
										
										
											2018-10-29 08:34:42 +00:00
										 |  |  | 	// amd64:`DECQ\s64\([A-Z]+\)` | 
					
						
							|  |  |  | 	arr[8]-- | 
					
						
							| 
									
										
										
										
											2018-04-15 09:31:39 +00:00
										 |  |  | 	// 386:"SUBL\t4" | 
					
						
							|  |  |  | 	// amd64:"SUBQ\t8" | 
					
						
							|  |  |  | 	return arr[0] - arr[1] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | // -------------------- // | 
					
						
							|  |  |  | //    Multiplication    // | 
					
						
							|  |  |  | // -------------------- // | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 10:57:10 +01:00
										 |  |  | func Pow2Muls(n1, n2 int) (int, int) { | 
					
						
							|  |  |  | 	// amd64:"SHLQ\t[$]5",-"IMULQ" | 
					
						
							|  |  |  | 	// 386:"SHLL\t[$]5",-"IMULL" | 
					
						
							|  |  |  | 	// arm:"SLL\t[$]5",-"MUL" | 
					
						
							|  |  |  | 	// arm64:"LSL\t[$]5",-"MUL" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"SLD\t[$]5",-"MUL" | 
					
						
							|  |  |  | 	// ppc64le:"SLD\t[$]5",-"MUL" | 
					
						
							| 
									
										
										
										
											2018-03-08 10:57:10 +01:00
										 |  |  | 	a := n1 * 32 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// amd64:"SHLQ\t[$]6",-"IMULQ" | 
					
						
							|  |  |  | 	// 386:"SHLL\t[$]6",-"IMULL" | 
					
						
							|  |  |  | 	// arm:"SLL\t[$]6",-"MUL" | 
					
						
							| 
									
										
										
										
											2018-09-27 06:21:14 +00:00
										 |  |  | 	// arm64:`NEG\sR[0-9]+<<6,\sR[0-9]+`,-`LSL`,-`MUL` | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"SLD\t[$]6","NEG\\sR[0-9]+,\\sR[0-9]+",-"MUL" | 
					
						
							|  |  |  | 	// ppc64le:"SLD\t[$]6","NEG\\sR[0-9]+,\\sR[0-9]+",-"MUL" | 
					
						
							| 
									
										
										
										
											2018-03-08 10:57:10 +01:00
										 |  |  | 	b := -64 * n2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return a, b | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-09 14:51:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-09 14:24:35 +02:00
										 |  |  | func Mul_96(n int) int { | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// amd64:`SHLQ\t[$]5`,`LEAQ\t\(.*\)\(.*\*2\),`,-`IMULQ` | 
					
						
							|  |  |  | 	// 386:`SHLL\t[$]5`,`LEAL\t\(.*\)\(.*\*2\),`,-`IMULL` | 
					
						
							|  |  |  | 	// arm64:`LSL\t[$]5`,`ADD\sR[0-9]+<<1,\sR[0-9]+`,-`MUL` | 
					
						
							|  |  |  | 	// arm:`SLL\t[$]5`,`ADD\sR[0-9]+<<1,\sR[0-9]+`,-`MUL` | 
					
						
							| 
									
										
										
										
											2018-04-09 14:24:35 +02:00
										 |  |  | 	return n * 96 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-24 07:04:21 +00:00
										 |  |  | func MulMemSrc(a []uint32, b []float32) { | 
					
						
							|  |  |  | 	// 386:`IMULL\s4\([A-Z]+\),\s[A-Z]+` | 
					
						
							|  |  |  | 	a[0] *= a[1] | 
					
						
							|  |  |  | 	// 386/sse2:`MULSS\s4\([A-Z]+\),\sX[0-9]+` | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// amd64:`MULSS\s4\([A-Z]+\),\sX[0-9]+` | 
					
						
							| 
									
										
										
										
											2018-06-24 07:04:21 +00:00
										 |  |  | 	b[0] *= b[1] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | // Multiplications merging tests | 
					
						
							| 
									
										
										
										
											2018-03-09 14:51:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func MergeMuls1(n int) int { | 
					
						
							| 
									
										
										
										
											2018-03-09 23:09:46 +03:00
										 |  |  | 	// amd64:"IMUL3Q\t[$]46" | 
					
						
							|  |  |  | 	// 386:"IMUL3L\t[$]46" | 
					
						
							| 
									
										
										
										
											2018-03-09 14:51:30 +01:00
										 |  |  | 	return 15*n + 31*n // 46n | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func MergeMuls2(n int) int { | 
					
						
							| 
									
										
										
										
											2018-03-09 23:09:46 +03:00
										 |  |  | 	// amd64:"IMUL3Q\t[$]23","ADDQ\t[$]29" | 
					
						
							|  |  |  | 	// 386:"IMUL3L\t[$]23","ADDL\t[$]29" | 
					
						
							| 
									
										
										
										
											2018-03-09 14:51:30 +01:00
										 |  |  | 	return 5*n + 7*(n+1) + 11*(n+2) // 23n + 29 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func MergeMuls3(a, n int) int { | 
					
						
							|  |  |  | 	// amd64:"ADDQ\t[$]19",-"IMULQ\t[$]19" | 
					
						
							|  |  |  | 	// 386:"ADDL\t[$]19",-"IMULL\t[$]19" | 
					
						
							|  |  |  | 	return a*n + 19*n // (a+19)n | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func MergeMuls4(n int) int { | 
					
						
							| 
									
										
										
										
											2018-03-09 23:09:46 +03:00
										 |  |  | 	// amd64:"IMUL3Q\t[$]14" | 
					
						
							|  |  |  | 	// 386:"IMUL3L\t[$]14" | 
					
						
							| 
									
										
										
										
											2018-03-09 14:51:30 +01:00
										 |  |  | 	return 23*n - 9*n // 14n | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func MergeMuls5(a, n int) int { | 
					
						
							|  |  |  | 	// amd64:"ADDQ\t[$]-19",-"IMULQ\t[$]19" | 
					
						
							|  |  |  | 	// 386:"ADDL\t[$]-19",-"IMULL\t[$]19" | 
					
						
							|  |  |  | 	return a*n - 19*n // (a-19)n | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // -------------- // | 
					
						
							|  |  |  | //    Division    // | 
					
						
							|  |  |  | // -------------- // | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-24 07:04:21 +00:00
										 |  |  | func DivMemSrc(a []float64) { | 
					
						
							|  |  |  | 	// 386/sse2:`DIVSD\s8\([A-Z]+\),\sX[0-9]+` | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// amd64:`DIVSD\s8\([A-Z]+\),\sX[0-9]+` | 
					
						
							| 
									
										
										
										
											2018-06-24 07:04:21 +00:00
										 |  |  | 	a[0] /= a[1] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | func Pow2Divs(n1 uint, n2 int) (uint, int) { | 
					
						
							|  |  |  | 	// 386:"SHRL\t[$]5",-"DIVL" | 
					
						
							|  |  |  | 	// amd64:"SHRQ\t[$]5",-"DIVQ" | 
					
						
							|  |  |  | 	// arm:"SRL\t[$]5",-".*udiv" | 
					
						
							|  |  |  | 	// arm64:"LSR\t[$]5",-"UDIV" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"SRD" | 
					
						
							|  |  |  | 	// ppc64le:"SRD" | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	a := n1 / 32 // unsigned | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// amd64:"SARQ\t[$]6",-"IDIVQ" | 
					
						
							|  |  |  | 	// 386:"SARL\t[$]6",-"IDIVL" | 
					
						
							|  |  |  | 	// arm:"SRA\t[$]6",-".*udiv" | 
					
						
							|  |  |  | 	// arm64:"ASR\t[$]6",-"SDIV" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"SRAD" | 
					
						
							|  |  |  | 	// ppc64le:"SRAD" | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	b := n2 / 64 // signed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return a, b | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Check that constant divisions get turned into MULs | 
					
						
							|  |  |  | func ConstDivs(n1 uint, n2 int) (uint, int) { | 
					
						
							|  |  |  | 	// amd64:"MOVQ\t[$]-1085102592571150095","MULQ",-"DIVQ" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// 386:"MOVL\t[$]-252645135","MULL",-"DIVL" | 
					
						
							|  |  |  | 	// arm64:`MOVD`,`UMULH`,-`DIV` | 
					
						
							|  |  |  | 	// arm:`MOVW`,`MUL`,-`.*udiv` | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	a := n1 / 17 // unsigned | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// amd64:"MOVQ\t[$]-1085102592571150095","IMULQ",-"IDIVQ" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// 386:"MOVL\t[$]-252645135","IMULL",-"IDIVL" | 
					
						
							|  |  |  | 	// arm64:`MOVD`,`SMULH`,-`DIV` | 
					
						
							|  |  |  | 	// arm:`MOVW`,`MUL`,-`.*udiv` | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	b := n2 / 17 // signed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return a, b | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-21 10:14:18 +00:00
										 |  |  | func FloatDivs(a []float32) float32 { | 
					
						
							|  |  |  | 	// amd64:`DIVSS\s8\([A-Z]+\),\sX[0-9]+` | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// 386/sse2:`DIVSS\s8\([A-Z]+\),\sX[0-9]+` | 
					
						
							| 
									
										
										
										
											2018-06-21 10:14:18 +00:00
										 |  |  | 	return a[1] / a[2] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | func Pow2Mods(n1 uint, n2 int) (uint, int) { | 
					
						
							|  |  |  | 	// 386:"ANDL\t[$]31",-"DIVL" | 
					
						
							|  |  |  | 	// amd64:"ANDQ\t[$]31",-"DIVQ" | 
					
						
							|  |  |  | 	// arm:"AND\t[$]31",-".*udiv" | 
					
						
							|  |  |  | 	// arm64:"AND\t[$]31",-"UDIV" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"ANDCC\t[$]31" | 
					
						
							|  |  |  | 	// ppc64le:"ANDCC\t[$]31" | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	a := n1 % 32 // unsigned | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-23 22:04:38 -06:00
										 |  |  | 	// 386:"SHRL",-"IDIVL" | 
					
						
							|  |  |  | 	// amd64:"SHRQ",-"IDIVQ" | 
					
						
							|  |  |  | 	// arm:"SRA",-".*udiv" | 
					
						
							|  |  |  | 	// arm64:"ASR",-"REM" | 
					
						
							|  |  |  | 	// ppc64:"SRAD" | 
					
						
							|  |  |  | 	// ppc64le:"SRAD" | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	b := n2 % 64 // signed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return a, b | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-23 22:04:38 -06:00
										 |  |  | // Check that signed divisibility checks get converted to AND on low bits | 
					
						
							| 
									
										
										
										
											2019-09-08 21:50:07 -06:00
										 |  |  | func Pow2DivisibleSigned(n1, n2 int) (bool, bool) { | 
					
						
							| 
									
										
										
										
											2019-04-23 22:04:38 -06:00
										 |  |  | 	// 386:"TESTL\t[$]63",-"DIVL",-"SHRL" | 
					
						
							|  |  |  | 	// amd64:"TESTQ\t[$]63",-"DIVQ",-"SHRQ" | 
					
						
							|  |  |  | 	// arm:"AND\t[$]63",-".*udiv",-"SRA" | 
					
						
							|  |  |  | 	// arm64:"AND\t[$]63",-"UDIV",-"ASR" | 
					
						
							|  |  |  | 	// ppc64:"ANDCC\t[$]63",-"SRAD" | 
					
						
							|  |  |  | 	// ppc64le:"ANDCC\t[$]63",-"SRAD" | 
					
						
							| 
									
										
										
										
											2019-09-08 21:50:07 -06:00
										 |  |  | 	a := n1%64 == 0 // signed divisible | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 386:"TESTL\t[$]63",-"DIVL",-"SHRL" | 
					
						
							|  |  |  | 	// amd64:"TESTQ\t[$]63",-"DIVQ",-"SHRQ" | 
					
						
							|  |  |  | 	// arm:"AND\t[$]63",-".*udiv",-"SRA" | 
					
						
							|  |  |  | 	// arm64:"AND\t[$]63",-"UDIV",-"ASR" | 
					
						
							|  |  |  | 	// ppc64:"ANDCC\t[$]63",-"SRAD" | 
					
						
							|  |  |  | 	// ppc64le:"ANDCC\t[$]63",-"SRAD" | 
					
						
							|  |  |  | 	b := n2%64 != 0 // signed indivisible | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return a, b | 
					
						
							| 
									
										
										
										
											2019-04-23 22:04:38 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | // Check that constant modulo divs get turned into MULs | 
					
						
							|  |  |  | func ConstMods(n1 uint, n2 int) (uint, int) { | 
					
						
							|  |  |  | 	// amd64:"MOVQ\t[$]-1085102592571150095","MULQ",-"DIVQ" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// 386:"MOVL\t[$]-252645135","MULL",-"DIVL" | 
					
						
							|  |  |  | 	// arm64:`MOVD`,`UMULH`,-`DIV` | 
					
						
							|  |  |  | 	// arm:`MOVW`,`MUL`,-`.*udiv` | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	a := n1 % 17 // unsigned | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// amd64:"MOVQ\t[$]-1085102592571150095","IMULQ",-"IDIVQ" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// 386:"MOVL\t[$]-252645135","IMULL",-"IDIVL" | 
					
						
							|  |  |  | 	// arm64:`MOVD`,`SMULH`,-`DIV` | 
					
						
							|  |  |  | 	// arm:`MOVW`,`MUL`,-`.*udiv` | 
					
						
							| 
									
										
										
										
											2018-03-14 11:47:34 +01:00
										 |  |  | 	b := n2 % 17 // signed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return a, b | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-09 21:58:16 -07:00
										 |  |  | // Check that divisibility checks x%c==0 are converted to MULs and rotates | 
					
						
							| 
									
										
										
										
											2019-04-05 14:05:07 -06:00
										 |  |  | func Divisible(n1 uint, n2 int) (bool, bool, bool, bool) { | 
					
						
							| 
									
										
										
										
											2019-03-09 21:58:16 -07:00
										 |  |  | 	// amd64:"MOVQ\t[$]-6148914691236517205","IMULQ","ROLQ\t[$]63",-"DIVQ" | 
					
						
							|  |  |  | 	// 386:"IMUL3L\t[$]-1431655765","ROLL\t[$]31",-"DIVQ" | 
					
						
							|  |  |  | 	// arm64:"MOVD\t[$]-6148914691236517205","MUL","ROR",-"DIV" | 
					
						
							|  |  |  | 	// arm:"MUL","CMP\t[$]715827882",-".*udiv" | 
					
						
							|  |  |  | 	// ppc64:"MULLD","ROTL\t[$]63" | 
					
						
							|  |  |  | 	// ppc64le:"MULLD","ROTL\t[$]63" | 
					
						
							| 
									
										
										
										
											2019-04-05 14:05:07 -06:00
										 |  |  | 	evenU := n1%6 == 0 | 
					
						
							| 
									
										
										
										
											2019-03-09 21:58:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// amd64:"MOVQ\t[$]-8737931403336103397","IMULQ",-"ROLQ",-"DIVQ" | 
					
						
							|  |  |  | 	// 386:"IMUL3L\t[$]678152731",-"ROLL",-"DIVQ" | 
					
						
							|  |  |  | 	// arm64:"MOVD\t[$]-8737931403336103397","MUL",-"ROR",-"DIV" | 
					
						
							|  |  |  | 	// arm:"MUL","CMP\t[$]226050910",-".*udiv" | 
					
						
							|  |  |  | 	// ppc64:"MULLD",-"ROTL" | 
					
						
							|  |  |  | 	// ppc64le:"MULLD",-"ROTL" | 
					
						
							| 
									
										
										
										
											2019-04-05 14:05:07 -06:00
										 |  |  | 	oddU := n1%19 == 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// amd64:"IMULQ","ADD","ROLQ\t[$]63",-"DIVQ" | 
					
						
							|  |  |  | 	// 386:"IMUL3L\t[$]-1431655765","ADDL\t[$]715827882","ROLL\t[$]31",-"DIVQ" | 
					
						
							|  |  |  | 	// arm64:"MUL","ADD\t[$]3074457345618258602","ROR",-"DIV" | 
					
						
							|  |  |  | 	// arm:"MUL","ADD\t[$]715827882",-".*udiv" | 
					
						
							|  |  |  | 	// ppc64:"MULLD","ADD","ROTL\t[$]63" | 
					
						
							|  |  |  | 	// ppc64le:"MULLD","ADD","ROTL\t[$]63" | 
					
						
							|  |  |  | 	evenS := n2%6 == 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// amd64:"IMULQ","ADD",-"ROLQ",-"DIVQ" | 
					
						
							|  |  |  | 	// 386:"IMUL3L\t[$]678152731","ADDL\t[$]113025455",-"ROLL",-"DIVQ" | 
					
						
							|  |  |  | 	// arm64:"MUL","ADD\t[$]485440633518672410",-"ROR",-"DIV" | 
					
						
							|  |  |  | 	// arm:"MUL","ADD\t[$]113025455",-".*udiv" | 
					
						
							|  |  |  | 	// ppc64:"MULLD","ADD",-"ROTL" | 
					
						
							|  |  |  | 	// ppc64le:"MULLD","ADD",-"ROTL" | 
					
						
							|  |  |  | 	oddS := n2%19 == 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return evenU, oddU, evenS, oddS | 
					
						
							| 
									
										
										
										
											2019-03-09 21:58:16 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-06 19:50:38 +10:00
										 |  |  | // Check that fix-up code is not generated for divisions where it has been proven that | 
					
						
							|  |  |  | // that the divisor is not -1 or that the dividend is > MinIntNN. | 
					
						
							|  |  |  | func NoFix64A(divr int64) (int64, int64) { | 
					
						
							|  |  |  | 	var d int64 = 42 | 
					
						
							|  |  |  | 	var e int64 = 84 | 
					
						
							|  |  |  | 	if divr > 5 { | 
					
						
							|  |  |  | 		d /= divr // amd64:-"JMP" | 
					
						
							|  |  |  | 		e %= divr // amd64:-"JMP" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return d, e | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NoFix64B(divd int64) (int64, int64) { | 
					
						
							|  |  |  | 	var d int64 | 
					
						
							|  |  |  | 	var e int64 | 
					
						
							|  |  |  | 	var divr int64 = -1 | 
					
						
							|  |  |  | 	if divd > -9223372036854775808 { | 
					
						
							|  |  |  | 		d = divd / divr // amd64:-"JMP" | 
					
						
							|  |  |  | 		e = divd % divr // amd64:-"JMP" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return d, e | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NoFix32A(divr int32) (int32, int32) { | 
					
						
							|  |  |  | 	var d int32 = 42 | 
					
						
							|  |  |  | 	var e int32 = 84 | 
					
						
							|  |  |  | 	if divr > 5 { | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		d /= divr | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		e %= divr | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return d, e | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NoFix32B(divd int32) (int32, int32) { | 
					
						
							|  |  |  | 	var d int32 | 
					
						
							|  |  |  | 	var e int32 | 
					
						
							|  |  |  | 	var divr int32 = -1 | 
					
						
							|  |  |  | 	if divd > -2147483648 { | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		d = divd / divr | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		e = divd % divr | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return d, e | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NoFix16A(divr int16) (int16, int16) { | 
					
						
							|  |  |  | 	var d int16 = 42 | 
					
						
							|  |  |  | 	var e int16 = 84 | 
					
						
							|  |  |  | 	if divr > 5 { | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		d /= divr | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		e %= divr | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return d, e | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NoFix16B(divd int16) (int16, int16) { | 
					
						
							|  |  |  | 	var d int16 | 
					
						
							|  |  |  | 	var e int16 | 
					
						
							|  |  |  | 	var divr int16 = -1 | 
					
						
							|  |  |  | 	if divd > -32768 { | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		d = divd / divr | 
					
						
							|  |  |  | 		// amd64:-"JMP" | 
					
						
							|  |  |  | 		// 386:-"JMP" | 
					
						
							|  |  |  | 		e = divd % divr | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return d, e | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | // Check that len() and cap() calls divided by powers of two are | 
					
						
							|  |  |  | // optimized into shifts and ands | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func LenDiv1(a []int) int { | 
					
						
							|  |  |  | 	// 386:"SHRL\t[$]10" | 
					
						
							|  |  |  | 	// amd64:"SHRQ\t[$]10" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// arm64:"LSR\t[$]10",-"SDIV" | 
					
						
							|  |  |  | 	// arm:"SRL\t[$]10",-".*udiv" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"SRD"\t[$]10" | 
					
						
							|  |  |  | 	// ppc64le:"SRD"\t[$]10" | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | 	return len(a) / 1024 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func LenDiv2(s string) int { | 
					
						
							|  |  |  | 	// 386:"SHRL\t[$]11" | 
					
						
							|  |  |  | 	// amd64:"SHRQ\t[$]11" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// arm64:"LSR\t[$]11",-"SDIV" | 
					
						
							|  |  |  | 	// arm:"SRL\t[$]11",-".*udiv" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"SRD\t[$]11" | 
					
						
							|  |  |  | 	// ppc64le:"SRD\t[$]11" | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | 	return len(s) / (4097 >> 1) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func LenMod1(a []int) int { | 
					
						
							|  |  |  | 	// 386:"ANDL\t[$]1023" | 
					
						
							|  |  |  | 	// amd64:"ANDQ\t[$]1023" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// arm64:"AND\t[$]1023",-"SDIV" | 
					
						
							|  |  |  | 	// arm/6:"AND",-".*udiv" | 
					
						
							|  |  |  | 	// arm/7:"BFC",-".*udiv",-"AND" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"ANDCC\t[$]1023" | 
					
						
							|  |  |  | 	// ppc64le:"ANDCC\t[$]1023" | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | 	return len(a) % 1024 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func LenMod2(s string) int { | 
					
						
							|  |  |  | 	// 386:"ANDL\t[$]2047" | 
					
						
							|  |  |  | 	// amd64:"ANDQ\t[$]2047" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// arm64:"AND\t[$]2047",-"SDIV" | 
					
						
							|  |  |  | 	// arm/6:"AND",-".*udiv" | 
					
						
							|  |  |  | 	// arm/7:"BFC",-".*udiv",-"AND" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"ANDCC\t[$]2047" | 
					
						
							|  |  |  | 	// ppc64le:"ANDCC\t[$]2047" | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | 	return len(s) % (4097 >> 1) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func CapDiv(a []int) int { | 
					
						
							|  |  |  | 	// 386:"SHRL\t[$]12" | 
					
						
							|  |  |  | 	// amd64:"SHRQ\t[$]12" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// arm64:"LSR\t[$]12",-"SDIV" | 
					
						
							|  |  |  | 	// arm:"SRL\t[$]12",-".*udiv" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"SRD\t[$]12" | 
					
						
							|  |  |  | 	// ppc64le:"SRD\t[$]12" | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | 	return cap(a) / ((1 << 11) + 2048) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func CapMod(a []int) int { | 
					
						
							|  |  |  | 	// 386:"ANDL\t[$]4095" | 
					
						
							|  |  |  | 	// amd64:"ANDQ\t[$]4095" | 
					
						
							| 
									
										
										
										
											2018-11-30 09:30:36 +00:00
										 |  |  | 	// arm64:"AND\t[$]4095",-"SDIV" | 
					
						
							|  |  |  | 	// arm/6:"AND",-".*udiv" | 
					
						
							|  |  |  | 	// arm/7:"BFC",-".*udiv",-"AND" | 
					
						
							| 
									
										
										
										
											2018-10-15 12:53:07 -04:00
										 |  |  | 	// ppc64:"ANDCC\t[$]4095" | 
					
						
							|  |  |  | 	// ppc64le:"ANDCC\t[$]4095" | 
					
						
							| 
									
										
										
										
											2018-03-15 10:06:37 +01:00
										 |  |  | 	return cap(a) % ((1 << 11) + 2048) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-04-23 13:49:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | func AddMul(x int) int { | 
					
						
							|  |  |  | 	// amd64:"LEAQ\t1" | 
					
						
							|  |  |  | 	return 2*x + 1 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-08-13 10:38:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-27 13:21:03 +00:00
										 |  |  | func MULA(a, b, c uint32) (uint32, uint32, uint32) { | 
					
						
							|  |  |  | 	// arm:`MULA`,-`MUL\s` | 
					
						
							|  |  |  | 	// arm64:`MADDW`,-`MULW` | 
					
						
							|  |  |  | 	r0 := a*b + c | 
					
						
							| 
									
										
										
										
											2018-10-29 09:01:14 +00:00
										 |  |  | 	// arm:`MULA`,-`MUL\s` | 
					
						
							| 
									
										
										
										
											2018-09-27 13:21:03 +00:00
										 |  |  | 	// arm64:`MADDW`,-`MULW` | 
					
						
							|  |  |  | 	r1 := c*79 + a | 
					
						
							| 
									
										
										
										
											2018-10-29 09:01:14 +00:00
										 |  |  | 	// arm:`ADD`,-`MULA`,-`MUL\s` | 
					
						
							| 
									
										
										
										
											2018-09-27 13:21:03 +00:00
										 |  |  | 	// arm64:`ADD`,-`MADD`,-`MULW` | 
					
						
							|  |  |  | 	r2 := b*64 + c | 
					
						
							|  |  |  | 	return r0, r1, r2 | 
					
						
							| 
									
										
										
										
											2018-08-13 10:38:25 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-15 02:25:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | func MULS(a, b, c uint32) (uint32, uint32, uint32) { | 
					
						
							|  |  |  | 	// arm/7:`MULS`,-`MUL\s` | 
					
						
							| 
									
										
										
										
											2018-10-29 09:01:14 +00:00
										 |  |  | 	// arm/6:`SUB`,`MUL\s`,-`MULS` | 
					
						
							| 
									
										
										
										
											2018-10-15 02:25:10 +00:00
										 |  |  | 	// arm64:`MSUBW`,-`MULW` | 
					
						
							|  |  |  | 	r0 := c - a*b | 
					
						
							| 
									
										
										
										
											2018-10-29 09:01:14 +00:00
										 |  |  | 	// arm/7:`MULS`,-`MUL\s` | 
					
						
							|  |  |  | 	// arm/6:`SUB`,`MUL\s`,-`MULS` | 
					
						
							| 
									
										
										
										
											2018-10-15 02:25:10 +00:00
										 |  |  | 	// arm64:`MSUBW`,-`MULW` | 
					
						
							|  |  |  | 	r1 := a - c*79 | 
					
						
							| 
									
										
										
										
											2018-10-29 09:01:14 +00:00
										 |  |  | 	// arm/7:`SUB`,-`MULS`,-`MUL\s` | 
					
						
							| 
									
										
										
										
											2018-10-15 02:25:10 +00:00
										 |  |  | 	// arm64:`SUB`,-`MSUBW`,-`MULW` | 
					
						
							|  |  |  | 	r2 := c - b*64 | 
					
						
							|  |  |  | 	return r0, r1, r2 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-19 12:26:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | func addSpecial(a, b, c uint32) (uint32, uint32, uint32) { | 
					
						
							|  |  |  | 	// amd64:`INCL` | 
					
						
							|  |  |  | 	a++ | 
					
						
							|  |  |  | 	// amd64:`DECL` | 
					
						
							|  |  |  | 	b-- | 
					
						
							|  |  |  | 	// amd64:`SUBL.*-128` | 
					
						
							|  |  |  | 	c += 128 | 
					
						
							|  |  |  | 	return a, b, c | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-07 13:44:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Divide -> shift rules usually require fixup for negative inputs. | 
					
						
							|  |  |  | // If the input is non-negative, make sure the fixup is eliminated. | 
					
						
							|  |  |  | func divInt(v int64) int64 { | 
					
						
							|  |  |  | 	if v < 0 { | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// amd64:-`.*SARQ.*63,`, -".*SHRQ", ".*SARQ.*[$]9," | 
					
						
							|  |  |  | 	return v / 512 | 
					
						
							|  |  |  | } |