| // 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 | |
| // Div and mod rewrites, testing cmd/compile/internal/ssa/_gen/divmod.rules. | |
| // See comments there for "Case 1" etc. | |
| // Convert multiplication by a power of two to a shift. | |
| func mul32_uint8(i uint8) uint8 { | |
| // 386: "SHLL [$]5," | |
| // arm64: "LSL [$]5," | |
| return i * 32 | |
| } | |
| func mul32_uint16(i uint16) uint16 { | |
| // 386: "SHLL [$]5," | |
| // arm64: "LSL [$]5," | |
| return i * 32 | |
| } | |
| func mul32_uint32(i uint32) uint32 { | |
| // 386: "SHLL [$]5," | |
| // arm64: "LSL [$]5," | |
| return i * 32 | |
| } | |
| func mul32_uint64(i uint64) uint64 { | |
| // 386: "SHLL [$]5," | |
| // 386: "SHRL [$]27," | |
| // arm64: "LSL [$]5," | |
| return i * 32 | |
| } | |
| func mulNeg32_int8(i int8) int8 { | |
| // 386: "SHLL [$]5," | |
| // 386: "NEGL" | |
| // arm64: "NEG R[0-9]+<<5," | |
| return i * -32 | |
| } | |
| func mulNeg32_int16(i int16) int16 { | |
| // 386: "SHLL [$]5," | |
| // 386: "NEGL" | |
| // arm64: "NEG R[0-9]+<<5," | |
| return i * -32 | |
| } | |
| func mulNeg32_int32(i int32) int32 { | |
| // 386: "SHLL [$]5," | |
| // 386: "NEGL" | |
| // arm64: "NEG R[0-9]+<<5," | |
| return i * -32 | |
| } | |
| func mulNeg32_int64(i int64) int64 { | |
| // 386: "SHLL [$]5," | |
| // 386: "SHRL [$]27," | |
| // 386: "SBBL" | |
| // arm64: "NEG R[0-9]+<<5," | |
| return i * -32 | |
| } | |
| // Signed divide by power of 2. | |
| func div32_int8(i int8) int8 { | |
| // 386: "SARB [$]7," | |
| // 386: "SHRB [$]3," | |
| // 386: "ADDL" | |
| // 386: "SARB [$]5," | |
| // arm64: "SBFX [$]7, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>3," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]3," | |
| return i / 32 | |
| } | |
| func div32_int16(i int16) int16 { | |
| // 386: "SARW [$]15," | |
| // 386: "SHRW [$]11," | |
| // 386: "ADDL" | |
| // 386: "SARW [$]5," | |
| // arm64: "SBFX [$]15, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>11," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]11," | |
| return i / 32 | |
| } | |
| func div32_int32(i int32) int32 { | |
| // 386: "SARL [$]31," | |
| // 386: "SHRL [$]27," | |
| // 386: "ADDL" | |
| // 386: "SARL [$]5," | |
| // arm64: "SBFX [$]31, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>27," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]27," | |
| return i / 32 | |
| } | |
| func div32_int64(i int64) int64 { | |
| // 386: "SARL [$]31," | |
| // 386: "SHRL [$]27," | |
| // 386: "ADDL" | |
| // 386: "SARL [$]5," | |
| // 386: "SHRL [$]5," | |
| // 386: "SHLL [$]27," | |
| // arm64: "ASR [$]63," | |
| // arm64: "ADD R[0-9]+>>59," | |
| // arm64: "ASR [$]5," | |
| return i / 32 | |
| } | |
| // Case 1. Signed divides where 2N ≤ register size. | |
| func div7_int8(i int8) int8 { | |
| // 386: "SARL [$]31," | |
| // 386: "IMUL3L [$]147," | |
| // 386: "SARL [$]10," | |
| // 386: "SUBL" | |
| // arm64: "MOVD [$]147," | |
| // arm64: "MULW" | |
| // arm64: "SBFX [$]10, R[0-9]+, [$]22," | |
| // arm64: "SUB R[0-9]+->31," | |
| // wasm: "I64Const [$]147" | |
| return i / 7 | |
| } | |
| func div7_int16(i int16) int16 { | |
| // 386: "SARL [$]31," | |
| // 386: "IMUL3L [$]37450," | |
| // 386: "SARL [$]18," | |
| // 386: "SUBL" | |
| // arm64: "MOVD [$]37450," | |
| // arm64: "MULW" | |
| // arm64: "SBFX [$]18, R[0-9]+, [$]14," | |
| // arm64: "SUB R[0-9]+->31," | |
| // wasm: "I64Const [$]37450" | |
| return i / 7 | |
| } | |
| func div7_int32(i int32) int32 { | |
| // 64-bit only | |
| // arm64: "MOVD [$]2454267027," | |
| // arm64: "MUL " | |
| // arm64: "ASR [$]34," | |
| // arm64: "SUB R[0-9]+->63," | |
| // wasm: "I64Const [$]2454267027" | |
| return i / 7 | |
| } | |
| // Case 2. Signed divides where m is even. | |
| func div9_int32(i int32) int32 { | |
| // 386: "SARL [$]31," | |
| // 386: "MOVL [$]1908874354," | |
| // 386: "IMULL" | |
| // 386: "SARL [$]2," | |
| // 386: "SUBL" | |
| // arm64: "MOVD [$]3817748708," | |
| // arm64: "MUL " | |
| // arm64: "ASR [$]35," | |
| // arm64: "SUB R[0-9]+->63," | |
| // wasm: "I64Const [$]3817748708" | |
| return i / 9 | |
| } | |
| func div7_int64(i int64) int64 { | |
| // 64-bit only | |
| // arm64 MOVD $5270498306774157605, SMULH, ASR $1, SUB ->63 | |
| // arm64: "MOVD [$]5270498306774157605," | |
| // arm64: "SMULH" | |
| // arm64: "ASR [$]1," | |
| // arm64: "SUB R[0-9]+->63," | |
| // wasm: "I64Const [$]613566757" | |
| // wasm: "I64Const [$]1227133513" | |
| return i / 7 | |
| } | |
| // Case 3. Signed divides where m is odd. | |
| func div3_int32(i int32) int32 { | |
| // 386: "SARL [$]31," | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "IMULL" | |
| // 386: "SARL [$]1," | |
| // 386: "SUBL" | |
| // arm64: "MOVD [$]2863311531," | |
| // arm64: "MUL" | |
| // arm64: "ASR [$]33," | |
| // arm64: "SUB R[0-9]+->63," | |
| // wasm: "I64Const [$]2863311531" | |
| return i / 3 | |
| } | |
| func div3_int64(i int64) int64 { | |
| // 64-bit only | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "SMULH" | |
| // arm64: "ADD" | |
| // arm64: "ASR [$]1," | |
| // arm64: "SUB R[0-9]+->63," | |
| // wasm: "I64Const [$]-1431655766" | |
| // wasm: "I64Const [$]2863311531" | |
| return i / 3 | |
| } | |
| // Case 4. Unsigned divide where x < 1<<(N-1). | |
| func div7_int16u(i int16) int16 { | |
| if i < 0 { | |
| return 0 | |
| } | |
| // 386: "IMUL3L [$]37450," | |
| // 386: "SHRL [$]18," | |
| // 386: -"SUBL" | |
| // arm64: "MOVD [$]37450," | |
| // arm64: "MULW" | |
| // arm64: "UBFX [$]18, R[0-9]+, [$]14," | |
| // arm64: -"SUB" | |
| // wasm: "I64Const [$]37450" | |
| // wasm -"I64Sub" | |
| return i / 7 | |
| } | |
| func div7_int32u(i int32) int32 { | |
| if i < 0 { | |
| return 0 | |
| } | |
| // 386: "MOVL [$]-1840700269," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]2" | |
| // 386: -"SUBL" | |
| // arm64: "MOVD [$]2454267027," | |
| // arm64: "MUL" | |
| // arm64: "LSR [$]34," | |
| // arm64: -"SUB" | |
| // wasm: "I64Const [$]2454267027" | |
| // wasm -"I64Sub" | |
| return i / 7 | |
| } | |
| func div7_int64u(i int64) int64 { | |
| // 64-bit only | |
| if i < 0 { | |
| return 0 | |
| } | |
| // arm64: "MOVD [$]-7905747460161236406," | |
| // arm64: "UMULH" | |
| // arm64: "LSR [$]2," | |
| // arm64: -"SUB" | |
| // wasm: "I64Const [$]1227133514" | |
| // wasm: "I64Const [$]2454267026" | |
| // wasm -"I64Sub" | |
| return i / 7 | |
| } | |
| // Case 5. Unsigned divide where 2N+1 ≤ register size. | |
| func div7_uint8(i uint8) uint8 { | |
| // 386: "IMUL3L [$]293," | |
| // 386: "SHRL [$]11," | |
| // arm64: "MOVD [$]293," | |
| // arm64: "MULW" | |
| // arm64: "UBFX [$]11, R[0-9]+, [$]21," | |
| // wasm: "I64Const [$]293" | |
| return i / 7 | |
| } | |
| func div7_uint16(i uint16) uint16 { | |
| // only 64-bit | |
| // arm64: "MOVD [$]74899," | |
| // arm64: "MUL" | |
| // arm64: "LSR [$]19," | |
| // wasm: "I64Const [$]74899" | |
| return i / 7 | |
| } | |
| // Case 6. Unsigned divide where m is even. | |
| func div3_uint16(i uint16) uint16 { | |
| // 386: "IMUL3L [$]43691," "SHRL [$]17," | |
| // arm64: "MOVD [$]87382," | |
| // arm64: "MUL" | |
| // arm64: "LSR [$]18," | |
| // wasm: "I64Const [$]87382" | |
| return i / 3 | |
| } | |
| func div3_uint32(i uint32) uint32 { | |
| // 386: "MOVL [$]-1431655765," "MULL", "SHRL [$]1," | |
| // arm64: "MOVD [$]2863311531," | |
| // arm64: "MUL" | |
| // arm64: "LSR [$]33," | |
| // wasm: "I64Const [$]2863311531" | |
| return i / 3 | |
| } | |
| func div3_uint64(i uint64) uint64 { | |
| // 386: "MOVL [$]-1431655766" | |
| // 386: "MULL" | |
| // 386: "SHRL [$]1" | |
| // 386 -".*CALL" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "UMULH" | |
| // arm64: "LSR [$]1," | |
| // wasm: "I64Const [$]2863311530" | |
| // wasm: "I64Const [$]2863311531" | |
| return i / 3 | |
| } | |
| // Case 7. Unsigned divide where c is even. | |
| func div14_uint16(i uint16) uint16 { | |
| // 32-bit only | |
| // 386: "SHRL [$]1," | |
| // 386: "IMUL3L [$]37450," | |
| // 386: "SHRL [$]18," | |
| return i / 14 | |
| } | |
| func div14_uint32(i uint32) uint32 { | |
| // 386: "SHRL [$]1," | |
| // 386: "MOVL [$]-1840700269," | |
| // 386: "SHRL [$]2," | |
| // arm64: "UBFX [$]1, R[0-9]+, [$]31," | |
| // arm64: "MOVD [$]2454267027," | |
| // arm64: "MUL" | |
| // arm64: "LSR [$]34," | |
| // wasm: "I64Const [$]2454267027" | |
| return i / 14 | |
| } | |
| func div14_uint64(i uint64) uint64 { | |
| // 386: "MOVL [$]-1840700270," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]2," | |
| // 386: -".*CALL" | |
| // arm64: "MOVD [$]-7905747460161236406," | |
| // arm64: "UMULH" | |
| // arm64: "LSR [$]2," | |
| // wasm: "I64Const [$]1227133514" | |
| // wasm: "I64Const [$]2454267026" | |
| return i / 14 | |
| } | |
| // Case 8. Unsigned divide on systems with avg. | |
| func div7_uint16a(i uint16) uint16 { | |
| // only 32-bit | |
| // 386: "SHLL [$]16," | |
| // 386: "IMUL3L [$]9363," | |
| // 386: "ADDL" | |
| // 386: "RCRL [$]1," | |
| // 386: "SHRL [$]18," | |
| return i / 7 | |
| } | |
| func div7_uint32(i uint32) uint32 { | |
| // 386: "MOVL [$]613566757," | |
| // 386: "MULL" | |
| // 386: "ADDL" | |
| // 386: "RCRL [$]1," | |
| // 386: "SHRL [$]2," | |
| // arm64: "UBFIZ [$]32, R[0-9]+, [$]32," | |
| // arm64: "MOVD [$]613566757," | |
| // arm64: "MUL" | |
| // arm64: "SUB" | |
| // arm64: "ADD R[0-9]+>>1," | |
| // arm64: "LSR [$]34," | |
| // wasm: "I64Const [$]613566757" | |
| return i / 7 | |
| } | |
| func div7_uint64(i uint64) uint64 { | |
| // 386: "MOVL [$]-1840700269," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]2," | |
| // 386: -".*CALL" | |
| // arm64: "MOVD [$]2635249153387078803," | |
| // arm64: "UMULH" | |
| // arm64: "SUB", | |
| // arm64: "ADD R[0-9]+>>1," | |
| // arm64: "LSR [$]2," | |
| // wasm: "I64Const [$]613566756" | |
| // wasm: "I64Const [$]2454267027" | |
| return i / 7 | |
| } | |
| func div12345_uint64(i uint64) uint64 { | |
| // 386: "MOVL [$]-1444876402," | |
| // 386: "MOVL [$]835683390," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]13," | |
| // 386: "SHLL [$]19," | |
| // arm64: "MOVD [$]-6205696892516465602," | |
| // arm64: "UMULH" | |
| // arm64: "LSR [$]13," | |
| // wasm: "I64Const [$]835683390" | |
| // wasm: "I64Const [$]2850090894" | |
| return i / 12345 | |
| } | |
| // Divisibility and non-divisibility by power of two. | |
| func divis32_uint8(i uint8) bool { | |
| // 386: "TESTB [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_uint8(i uint8) bool { | |
| // 386: "TESTB [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 != 0 | |
| } | |
| func divis32_uint16(i uint16) bool { | |
| // 386: "TESTW [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_uint16(i uint16) bool { | |
| // 386: "TESTW [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 != 0 | |
| } | |
| func divis32_uint32(i uint32) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_uint32(i uint32) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 != 0 | |
| } | |
| func divis32_uint64(i uint64) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TST [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_uint64(i uint64) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TST [$]31," | |
| return i%32 != 0 | |
| } | |
| func divis32_int8(i int8) bool { | |
| // 386: "TESTB [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_int8(i int8) bool { | |
| // 386: "TESTB [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 != 0 | |
| } | |
| func divis32_int16(i int16) bool { | |
| // 386: "TESTW [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_int16(i int16) bool { | |
| // 386: "TESTW [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 != 0 | |
| } | |
| func divis32_int32(i int32) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_int32(i int32) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TSTW [$]31," | |
| return i%32 != 0 | |
| } | |
| func divis32_int64(i int64) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TST [$]31," | |
| return i%32 == 0 | |
| } | |
| func ndivis32_int64(i int64) bool { | |
| // 386: "TESTL [$]31," | |
| // arm64: "TST [$]31," | |
| return i%32 != 0 | |
| } | |
| // Divide with divisibility check; reuse divide intermediate mod. | |
| func div_divis32_uint8(i uint8) (uint8, bool) { | |
| // 386: "SHRB [$]5," | |
| // 386: "TESTB [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "UBFX [$]5, R[0-9]+, [$]3" | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_uint8(i uint8) (uint8, bool) { | |
| // 386: "SHRB [$]5," | |
| // 386: "TESTB [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "UBFX [$]5, R[0-9]+, [$]3" | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| func div_divis32_uint16(i uint16) (uint16, bool) { | |
| // 386: "SHRW [$]5," | |
| // 386: "TESTW [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "UBFX [$]5, R[0-9]+, [$]11" | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_uint16(i uint16) (uint16, bool) { | |
| // 386: "SHRW [$]5," | |
| // 386: "TESTW [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "UBFX [$]5, R[0-9]+, [$]11," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| func div_divis32_uint32(i uint32) (uint32, bool) { | |
| // 386: "SHRL [$]5," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "UBFX [$]5, R[0-9]+, [$]27," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_uint32(i uint32) (uint32, bool) { | |
| // 386: "SHRL [$]5," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "UBFX [$]5, R[0-9]+, [$]27," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| func div_divis32_uint64(i uint64) (uint64, bool) { | |
| // 386: "SHRL [$]5," | |
| // 386: "SHLL [$]27," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "LSR [$]5," | |
| // arm64: "TST [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_uint64(i uint64) (uint64, bool) { | |
| // 386: "SHRL [$]5," | |
| // 386: "SHLL [$]27," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "LSR [$]5," | |
| // arm64: "TST [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| func div_divis32_int8(i int8) (int8, bool) { | |
| // 386: "SARB [$]7," | |
| // 386: "SHRB [$]3," | |
| // 386: "SARB [$]5," | |
| // 386: "TESTB [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "SBFX [$]7, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>3," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]3," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_int8(i int8) (int8, bool) { | |
| // 386: "SARB [$]7," | |
| // 386: "SHRB [$]3," | |
| // 386: "SARB [$]5," | |
| // 386: "TESTB [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "SBFX [$]7, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>3," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]3," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| func div_divis32_int16(i int16) (int16, bool) { | |
| // 386: "SARW [$]15," | |
| // 386: "SHRW [$]11," | |
| // 386: "SARW [$]5," | |
| // 386: "TESTW [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "SBFX [$]15, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>11," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]11," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_int16(i int16) (int16, bool) { | |
| // 386: "SARW [$]15," | |
| // 386: "SHRW [$]11," | |
| // 386: "SARW [$]5," | |
| // 386: "TESTW [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "SBFX [$]15, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>11," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]11," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| func div_divis32_int32(i int32) (int32, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "SHRL [$]27," | |
| // 386: "SARL [$]5," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "SBFX [$]31, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>27," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]27," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_int32(i int32) (int32, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "SHRL [$]27," | |
| // 386: "SARL [$]5," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "SBFX [$]31, R[0-9]+, [$]1," | |
| // arm64: "ADD R[0-9]+>>27," | |
| // arm64: "SBFX [$]5, R[0-9]+, [$]27," | |
| // arm64: "TSTW [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| func div_divis32_int64(i int64) (int64, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "SHRL [$]27," | |
| // 386: "SARL [$]5," | |
| // 386: "SHLL [$]27," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETEQ" | |
| // arm64: "ASR [$]63," | |
| // arm64: "ADD R[0-9]+>>59," | |
| // arm64: "ASR [$]5," | |
| // arm64: "TST [$]31," | |
| // arm64: "CSET EQ" | |
| return i / 32, i%32 == 0 | |
| } | |
| func div_ndivis32_int64(i int64) (int64, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "SHRL [$]27," | |
| // 386: "SARL [$]5," | |
| // 386: "SHLL [$]27," | |
| // 386: "TESTL [$]31,", | |
| // 386: "SETNE" | |
| // arm64: "ASR [$]63," | |
| // arm64: "ADD R[0-9]+>>59," | |
| // arm64: "ASR [$]5," | |
| // arm64: "TST [$]31," | |
| // arm64: "CSET NE" | |
| return i / 32, i%32 != 0 | |
| } | |
| // Divisibility and non-divisibility by non-power-of-two. | |
| func divis6_uint8(i uint8) bool { | |
| // 386: "IMUL3L [$]-85," | |
| // 386: "ROLB [$]7," | |
| // 386: "CMPB .*, [$]42" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-85," | |
| // arm64: "MULW" | |
| // arm64: "UBFX [$]1, R[0-9]+, [$]7," | |
| // arm64: "ORR R[0-9]+<<7" | |
| // arm64: "CMPW [$]42," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_uint8(i uint8) bool { | |
| // 386: "IMUL3L [$]-85," | |
| // 386: "ROLB [$]7," | |
| // 386: "CMPB .*, [$]42" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-85," | |
| // arm64: "MULW" | |
| // arm64: "UBFX [$]1, R[0-9]+, [$]7," | |
| // arm64: "ORR R[0-9]+<<7" | |
| // arm64: "CMPW [$]42," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func divis6_uint16(i uint16) bool { | |
| // 386: "IMUL3L [$]-21845," | |
| // 386: "ROLW [$]15," | |
| // 386: "CMPW .*, [$]10922" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-21845," | |
| // arm64: "MULW" | |
| // arm64: "ORR R[0-9]+<<16" | |
| // arm64: "RORW [$]17," | |
| // arm64: "MOVD [$]10922," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_uint16(i uint16) bool { | |
| // 386: "IMUL3L [$]-21845," | |
| // 386: "ROLW [$]15," | |
| // 386: "CMPW .*, [$]10922" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-21845," | |
| // arm64: "MULW" | |
| // arm64: "ORR R[0-9]+<<16" | |
| // arm64: "RORW [$]17," | |
| // arm64: "MOVD [$]10922," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func divis6_uint32(i uint32) bool { | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "ROLL [$]31," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-1431655765," | |
| // arm64: "MULW" | |
| // arm64: "RORW [$]1," | |
| // arm64: "MOVD [$]715827882," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_uint32(i uint32) bool { | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "ROLL [$]31," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-1431655765," | |
| // arm64: "MULW" | |
| // arm64: "RORW [$]1," | |
| // arm64: "MOVD [$]715827882," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func divis6_uint64(i uint64) bool { | |
| // 386: "IMUL3L [$]-1431655766," | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]1," | |
| // 386: "SHLL [$]31," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "MUL " | |
| // arm64: "ROR [$]1," | |
| // arm64: "MOVD [$]3074457345618258602," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_uint64(i uint64) bool { | |
| // 386: "IMUL3L [$]-1431655766," | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]1," | |
| // 386: "SHLL [$]31," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "MUL " | |
| // arm64: "ROR [$]1," | |
| // arm64: "MOVD [$]3074457345618258602," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func divis6_int8(i int8) bool { | |
| // 386: "IMUL3L [$]-85," | |
| // 386: "ADDL [$]42," | |
| // 386: "ROLB [$]7," | |
| // 386: "CMPB .*, [$]42" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-85," | |
| // arm64: "MULW" | |
| // arm64: "ADD [$]42," | |
| // arm64: "UBFX [$]1, R[0-9]+, [$]7," | |
| // arm64: "ORR R[0-9]+<<7" | |
| // arm64: "CMPW [$]42," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_int8(i int8) bool { | |
| // 386: "IMUL3L [$]-85," | |
| // 386: "ADDL [$]42," | |
| // 386: "ROLB [$]7," | |
| // 386: "CMPB .*, [$]42" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-85," | |
| // arm64: "MULW" | |
| // arm64: "ADD [$]42," | |
| // arm64: "UBFX [$]1, R[0-9]+, [$]7," | |
| // arm64: "ORR R[0-9]+<<7" | |
| // arm64: "CMPW [$]42," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func divis6_int16(i int16) bool { | |
| // 386: "IMUL3L [$]-21845," | |
| // 386: "ADDL [$]10922," | |
| // 386: "ROLW [$]15," | |
| // 386: "CMPW .*, [$]10922" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-21845," | |
| // arm64: "MULW" | |
| // arm64: "MOVD [$]10922," | |
| // arm64: "ADD " | |
| // arm64: "ORR R[0-9]+<<16" | |
| // arm64: "RORW [$]17," | |
| // arm64: "MOVD [$]10922," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_int16(i int16) bool { | |
| // 386: "IMUL3L [$]-21845," | |
| // 386: "ADDL [$]10922," | |
| // 386: "ROLW [$]15," | |
| // 386: "CMPW .*, [$]10922" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-21845," | |
| // arm64: "MULW" | |
| // arm64: "MOVD [$]10922," | |
| // arm64: "ADD " | |
| // arm64: "ORR R[0-9]+<<16" | |
| // arm64: "RORW [$]17," | |
| // arm64: "MOVD [$]10922," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func divis6_int32(i int32) bool { | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "ADDL [$]715827882," | |
| // 386: "ROLL [$]31," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-1431655765," | |
| // arm64: "MULW" | |
| // arm64: "MOVD [$]715827882," | |
| // arm64: "ADD " | |
| // arm64: "RORW [$]1," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_int32(i int32) bool { | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "ADDL [$]715827882," | |
| // 386: "ROLL [$]31," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-1431655765," | |
| // arm64: "MULW" | |
| // arm64: "MOVD [$]715827882," | |
| // arm64: "ADD " | |
| // arm64: "RORW [$]1," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func divis6_int64(i int64) bool { | |
| // 386: "IMUL3L [$]-1431655766," | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "ADCL [$]715827882," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "CMPL .*, [$]-1431655766" | |
| // 386: "SETLS" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "MUL " | |
| // arm64: "MOVD [$]3074457345618258602," | |
| // arm64: "ADD " | |
| // arm64: "ROR [$]1," | |
| // arm64: "CSET LS" | |
| return i%6 == 0 | |
| } | |
| func ndivis6_int64(i int64) bool { | |
| // 386: "IMUL3L [$]-1431655766," | |
| // 386: "IMUL3L [$]-1431655765," | |
| // 386: "ADCL [$]715827882," | |
| // 386: "CMPL .*, [$]715827882" | |
| // 386: "CMPL .*, [$]-1431655766" | |
| // 386: "SETHI" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "MUL " | |
| // arm64: "MOVD [$]3074457345618258602," | |
| // arm64: "ADD " | |
| // arm64: "ROR [$]1," | |
| // arm64: "CSET HI" | |
| return i%6 != 0 | |
| } | |
| func div_divis6_uint8(i uint8) (uint8, bool) { | |
| // 386: "IMUL3L [$]342," | |
| // 386: "SHRL [$]11," | |
| // 386: "SETEQ" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]342," | |
| // arm64: "MULW" | |
| // arm64: "UBFX [$]11, R[0-9]+, [$]21," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_uint8(i uint8) (uint8, bool) { | |
| // 386: "IMUL3L [$]342," | |
| // 386: "SHRL [$]11," | |
| // 386: "SETNE" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]342," | |
| // arm64: "MULW" | |
| // arm64: "UBFX [$]11, R[0-9]+, [$]21," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |
| func div_divis6_uint16(i uint16) (uint16, bool) { | |
| // 386: "IMUL3L [$]43691," | |
| // 386: "SHRL [$]18," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETEQ" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]87382," | |
| // arm64: "MUL " | |
| // arm64: "LSR [$]19," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_uint16(i uint16) (uint16, bool) { | |
| // 386: "IMUL3L [$]43691," | |
| // 386: "SHRL [$]18," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETNE" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]87382," | |
| // arm64: "MUL " | |
| // arm64: "LSR [$]19," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |
| func div_divis6_uint32(i uint32) (uint32, bool) { | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "SHRL [$]2," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETEQ" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]2863311531," | |
| // arm64: "MUL " | |
| // arm64: "LSR [$]34," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_uint32(i uint32) (uint32, bool) { | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "SHRL [$]2," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETNE" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]2863311531," | |
| // arm64: "MUL " | |
| // arm64: "LSR [$]34," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |
| func div_divis6_uint64(i uint64) (uint64, bool) { | |
| // 386: "MOVL [$]-1431655766," | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]2," | |
| // 386: "SHLL [$]30," | |
| // 386: "SETEQ" | |
| // 386: -".*CALL" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "UMULH" | |
| // arm64: "LSR [$]2," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_uint64(i uint64) (uint64, bool) { | |
| // 386: "MOVL [$]-1431655766," | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "MULL" | |
| // 386: "SHRL [$]2," | |
| // 386: "SHLL [$]30," | |
| // 386: "SETNE" | |
| // 386: -".*CALL" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "UMULH" | |
| // arm64: "LSR [$]2," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |
| func div_divis6_int8(i int8) (int8, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "IMUL3L [$]171," | |
| // 386: "SARL [$]10," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETEQ" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]171," | |
| // arm64: "MULW" | |
| // arm64: "SBFX [$]10, R[0-9]+, [$]22," | |
| // arm64: "SUB R[0-9]+->31," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_int8(i int8) (int8, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "IMUL3L [$]171," | |
| // 386: "SARL [$]10," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETNE" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]171," | |
| // arm64: "MULW" | |
| // arm64: "SBFX [$]10, R[0-9]+, [$]22," | |
| // arm64: "SUB R[0-9]+->31," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |
| func div_divis6_int16(i int16) (int16, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "IMUL3L [$]43691," | |
| // 386: "SARL [$]18," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETEQ" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]43691," | |
| // arm64: "MULW" | |
| // arm64: "SBFX [$]18, R[0-9]+, [$]14," | |
| // arm64: "SUB R[0-9]+->31," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_int16(i int16) (int16, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "IMUL3L [$]43691," | |
| // 386: "SARL [$]18," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETNE" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]43691," | |
| // arm64: "MULW" | |
| // arm64: "SBFX [$]18, R[0-9]+, [$]14," | |
| // arm64: "SUB R[0-9]+->31," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |
| func div_divis6_int32(i int32) (int32, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "IMULL" | |
| // 386: "SARL [$]2," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETEQ" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]2863311531," | |
| // arm64: "MUL " | |
| // arm64: "ASR [$]34," | |
| // arm64: "SUB R[0-9]+->63," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_int32(i int32) (int32, bool) { | |
| // 386: "SARL [$]31," | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "IMULL" | |
| // 386: "SARL [$]2," | |
| // 386: "SHLL [$]1," | |
| // 386: "SETNE" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]2863311531," | |
| // arm64: "MUL " | |
| // arm64: "ASR [$]34," | |
| // arm64: "SUB R[0-9]+->63," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |
| func div_divis6_int64(i int64) (int64, bool) { | |
| // 386: "ANDL [$]-1431655766," | |
| // 386: "ANDL [$]-1431655765," | |
| // 386: "MOVL [$]-1431655766," | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "SUBL" "SBBL" | |
| // 386: "MULL" | |
| // 386: "SETEQ" | |
| // 386: -"SET(LS|HI)" | |
| // 386: -".*CALL" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "SMULH" | |
| // arm64: "ADD" | |
| // arm64: "ASR [$]2," | |
| // arm64: "SUB R[0-9]+->63," | |
| // arm64: "CSET EQ" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 == 0 | |
| } | |
| func div_ndivis6_int64(i int64) (int64, bool) { | |
| // 386: "ANDL [$]-1431655766," | |
| // 386: "ANDL [$]-1431655765," | |
| // 386: "MOVL [$]-1431655766," | |
| // 386: "MOVL [$]-1431655765," | |
| // 386: "SUBL" "SBBL" | |
| // 386: "MULL" | |
| // 386: "SETNE" | |
| // 386: -"SET(LS|HI)" | |
| // 386: -".*CALL" | |
| // 386: -"RO[RL]" | |
| // arm64: "MOVD [$]-6148914691236517205," | |
| // arm64: "SMULH" | |
| // arm64: "ADD" | |
| // arm64: "ASR [$]2," | |
| // arm64: "SUB R[0-9]+->63," | |
| // arm64: "CSET NE" | |
| // arm64: -"RO[RL]" | |
| return i / 6, i%6 != 0 | |
| } | |