go/test/codegen/bits.go
Ben Shi b75c5c5992 cmd/compile: optimize AMD64 with more read-modify-write operations
6 more operations which do read-modify-write with a constant
source operand are added.

1. The total size of pkg/linux_amd64 decreases about 3KB, excluding
cmd/compile.

2. The go1 benckmark shows a slight improvement.
name                     old time/op    new time/op    delta
BinaryTree17-4              2.61s ± 4%     2.67s ± 2%  +2.26%  (p=0.000 n=30+29)
Fannkuch11-4                2.39s ± 2%     2.32s ± 2%  -2.67%  (p=0.000 n=30+30)
FmtFprintfEmpty-4          44.0ns ± 4%    41.7ns ± 4%  -5.15%  (p=0.000 n=30+30)
FmtFprintfString-4         74.2ns ± 4%    72.3ns ± 4%  -2.59%  (p=0.000 n=30+30)
FmtFprintfInt-4            81.7ns ± 3%    78.8ns ± 4%  -3.54%  (p=0.000 n=27+30)
FmtFprintfIntInt-4          130ns ± 4%     124ns ± 5%  -4.60%  (p=0.000 n=30+30)
FmtFprintfPrefixedInt-4     154ns ± 3%     152ns ± 3%  -1.13%  (p=0.012 n=30+30)
FmtFprintfFloat-4           215ns ± 4%     212ns ± 5%  -1.56%  (p=0.002 n=30+30)
FmtManyArgs-4               522ns ± 3%     512ns ± 3%  -1.84%  (p=0.001 n=30+30)
GobDecode-4                6.42ms ± 5%    6.49ms ± 7%    ~     (p=0.070 n=30+30)
GobEncode-4                6.07ms ± 8%    5.98ms ± 8%    ~     (p=0.150 n=30+30)
Gzip-4                      236ms ± 4%     223ms ± 4%  -5.57%  (p=0.000 n=30+30)
Gunzip-4                   37.4ms ± 3%    36.7ms ± 4%  -2.03%  (p=0.000 n=30+30)
HTTPClientServer-4         58.7µs ± 1%    58.5µs ± 2%  -0.37%  (p=0.018 n=30+29)
JSONEncode-4               12.0ms ± 4%    12.1ms ± 3%    ~     (p=0.112 n=30+30)
JSONDecode-4               54.5ms ± 3%    55.5ms ± 4%  +1.80%  (p=0.006 n=30+30)
Mandelbrot200-4            3.78ms ± 4%    3.78ms ± 4%    ~     (p=0.173 n=30+30)
GoParse-4                  3.16ms ± 5%    3.22ms ± 5%  +1.75%  (p=0.010 n=30+30)
RegexpMatchEasy0_32-4      76.6ns ± 1%    75.9ns ± 3%    ~     (p=0.672 n=25+30)
RegexpMatchEasy0_1K-4       252ns ± 3%     253ns ± 3%  +0.57%  (p=0.027 n=30+30)
RegexpMatchEasy1_32-4      69.8ns ± 4%    70.2ns ± 6%    ~     (p=0.539 n=30+30)
RegexpMatchEasy1_1K-4       374ns ± 3%     373ns ± 5%    ~     (p=0.263 n=30+30)
RegexpMatchMedium_32-4      107ns ± 4%     109ns ± 3%    ~     (p=0.067 n=30+30)
RegexpMatchMedium_1K-4     33.9µs ± 5%    34.1µs ± 4%    ~     (p=0.297 n=30+30)
RegexpMatchHard_32-4       1.54µs ± 3%    1.56µs ± 4%  +1.43%  (p=0.002 n=30+30)
RegexpMatchHard_1K-4       46.6µs ± 3%    47.0µs ± 3%    ~     (p=0.055 n=30+30)
Revcomp-4                   411ms ± 6%     407ms ± 6%    ~     (p=0.219 n=30+30)
Template-4                 66.8ms ± 3%    64.8ms ± 5%  -3.01%  (p=0.000 n=30+30)
TimeParse-4                 312ns ± 2%     319ns ± 3%  +2.50%  (p=0.000 n=30+30)
TimeFormat-4                296ns ± 5%     299ns ± 3%  +0.93%  (p=0.005 n=30+30)
[Geo mean]                 47.5µs         47.1µs       -0.75%

name                     old speed      new speed      delta
GobDecode-4               120MB/s ± 5%   118MB/s ± 6%    ~     (p=0.072 n=30+30)
GobEncode-4               127MB/s ± 8%   129MB/s ± 8%    ~     (p=0.150 n=30+30)
Gzip-4                   82.1MB/s ± 4%  87.0MB/s ± 4%  +5.90%  (p=0.000 n=30+30)
Gunzip-4                  519MB/s ± 4%   529MB/s ± 4%  +2.07%  (p=0.001 n=30+30)
JSONEncode-4              162MB/s ± 4%   161MB/s ± 3%    ~     (p=0.110 n=30+30)
JSONDecode-4             35.6MB/s ± 3%  35.0MB/s ± 4%  -1.77%  (p=0.007 n=30+30)
GoParse-4                18.3MB/s ± 4%  18.0MB/s ± 4%  -1.72%  (p=0.009 n=30+30)
RegexpMatchEasy0_32-4     418MB/s ± 1%   422MB/s ± 3%    ~     (p=0.645 n=25+30)
RegexpMatchEasy0_1K-4    4.06GB/s ± 3%  4.04GB/s ± 3%  -0.57%  (p=0.033 n=30+30)
RegexpMatchEasy1_32-4     459MB/s ± 4%   456MB/s ± 6%    ~     (p=0.530 n=30+30)
RegexpMatchEasy1_1K-4    2.73GB/s ± 3%  2.75GB/s ± 5%    ~     (p=0.279 n=30+30)
RegexpMatchMedium_32-4   9.28MB/s ± 5%  9.18MB/s ± 4%    ~     (p=0.086 n=30+30)
RegexpMatchMedium_1K-4   30.2MB/s ± 4%  30.0MB/s ± 4%    ~     (p=0.300 n=30+30)
RegexpMatchHard_32-4     20.8MB/s ± 3%  20.5MB/s ± 4%  -1.41%  (p=0.002 n=30+30)
RegexpMatchHard_1K-4     22.0MB/s ± 3%  21.8MB/s ± 3%    ~     (p=0.051 n=30+30)
Revcomp-4                 619MB/s ± 7%   625MB/s ± 7%    ~     (p=0.219 n=30+30)
Template-4               29.0MB/s ± 3%  29.9MB/s ± 4%  +3.11%  (p=0.000 n=30+30)
[Geo mean]                123MB/s        123MB/s       +0.28%

Change-Id: I850652cfd53329c1af804b7f57f4393d8097bb0d
Reviewed-on: https://go-review.googlesource.com/121135
Run-TryBot: Ben Shi <powerman1st@163.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ilya Tocar <ilya.tocar@intel.com>
2018-08-20 14:18:39 +00:00

303 lines
4.7 KiB
Go

// 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
/************************************
* 64-bit instructions
************************************/
func bitcheck64_constleft(a uint64) (n int) {
// amd64:"BTQ\t[$]63"
if a&(1<<63) != 0 {
return 1
}
// amd64:"BTQ\t[$]60"
if a&(1<<60) != 0 {
return 1
}
// amd64:"BTL\t[$]0"
if a&(1<<0) != 0 {
return 1
}
return 0
}
func bitcheck64_constright(a [8]uint64) (n int) {
// amd64:"BTQ\t[$]63"
if (a[0]>>63)&1 != 0 {
return 1
}
// amd64:"BTQ\t[$]63"
if a[1]>>63 != 0 {
return 1
}
// amd64:"BTQ\t[$]63"
if a[2]>>63 == 0 {
return 1
}
// amd64:"BTQ\t[$]60"
if (a[3]>>60)&1 == 0 {
return 1
}
// amd64:"BTL\t[$]1"
if (a[4]>>1)&1 == 0 {
return 1
}
// amd64:"BTL\t[$]0"
if (a[5]>>0)&1 == 0 {
return 1
}
// amd64:"BTL\t[$]7"
if (a[6]>>5)&4 == 0 {
return 1
}
return 0
}
func bitcheck64_var(a, b uint64) (n int) {
// amd64:"BTQ"
if a&(1<<(b&63)) != 0 {
return 1
}
// amd64:"BTQ",-"BT.\t[$]0"
if (b>>(a&63))&1 != 0 {
return 1
}
return 0
}
func bitcheck64_mask(a uint64) (n int) {
// amd64:"BTQ\t[$]63"
if a&0x8000000000000000 != 0 {
return 1
}
// amd64:"BTQ\t[$]59"
if a&0x800000000000000 != 0 {
return 1
}
// amd64:"BTL\t[$]0"
if a&0x1 != 0 {
return 1
}
return 0
}
func biton64(a, b uint64) (n uint64) {
// amd64:"BTSQ"
n += b | (1 << (a & 63))
// amd64:"BTSQ\t[$]63"
n += a | (1 << 63)
// amd64:"BTSQ\t[$]60"
n += a | (1 << 60)
// amd64:"ORQ\t[$]1"
n += a | (1 << 0)
return n
}
func bitoff64(a, b uint64) (n uint64) {
// amd64:"BTRQ"
n += b &^ (1 << (a & 63))
// amd64:"BTRQ\t[$]63"
n += a &^ (1 << 63)
// amd64:"BTRQ\t[$]60"
n += a &^ (1 << 60)
// amd64:"ANDQ\t[$]-2"
n += a &^ (1 << 0)
return n
}
func bitcompl64(a, b uint64) (n uint64) {
// amd64:"BTCQ"
n += b ^ (1 << (a & 63))
// amd64:"BTCQ\t[$]63"
n += a ^ (1 << 63)
// amd64:"BTCQ\t[$]60"
n += a ^ (1 << 60)
// amd64:"XORQ\t[$]1"
n += a ^ (1 << 0)
return n
}
/************************************
* 32-bit instructions
************************************/
func bitcheck32_constleft(a uint32) (n int) {
// amd64:"BTL\t[$]31"
if a&(1<<31) != 0 {
return 1
}
// amd64:"BTL\t[$]28"
if a&(1<<28) != 0 {
return 1
}
// amd64:"BTL\t[$]0"
if a&(1<<0) != 0 {
return 1
}
return 0
}
func bitcheck32_constright(a [8]uint32) (n int) {
// amd64:"BTL\t[$]31"
if (a[0]>>31)&1 != 0 {
return 1
}
// amd64:"BTL\t[$]31"
if a[1]>>31 != 0 {
return 1
}
// amd64:"BTL\t[$]31"
if a[2]>>31 == 0 {
return 1
}
// amd64:"BTL\t[$]28"
if (a[3]>>28)&1 == 0 {
return 1
}
// amd64:"BTL\t[$]1"
if (a[4]>>1)&1 == 0 {
return 1
}
// amd64:"BTL\t[$]0"
if (a[5]>>0)&1 == 0 {
return 1
}
// amd64:"BTL\t[$]7"
if (a[6]>>5)&4 == 0 {
return 1
}
return 0
}
func bitcheck32_var(a, b uint32) (n int) {
// amd64:"BTL"
if a&(1<<(b&31)) != 0 {
return 1
}
// amd64:"BTL",-"BT.\t[$]0"
if (b>>(a&31))&1 != 0 {
return 1
}
return 0
}
func bitcheck32_mask(a uint32) (n int) {
// amd64:"BTL\t[$]31"
if a&0x80000000 != 0 {
return 1
}
// amd64:"BTL\t[$]27"
if a&0x8000000 != 0 {
return 1
}
// amd64:"BTL\t[$]0"
if a&0x1 != 0 {
return 1
}
return 0
}
func biton32(a, b uint32) (n uint32) {
// amd64:"BTSL"
n += b | (1 << (a & 31))
// amd64:"BTSL\t[$]31"
n += a | (1 << 31)
// amd64:"BTSL\t[$]28"
n += a | (1 << 28)
// amd64:"ORL\t[$]1"
n += a | (1 << 0)
return n
}
func bitoff32(a, b uint32) (n uint32) {
// amd64:"BTRL"
n += b &^ (1 << (a & 31))
// amd64:"BTRL\t[$]31"
n += a &^ (1 << 31)
// amd64:"BTRL\t[$]28"
n += a &^ (1 << 28)
// amd64:"ANDL\t[$]-2"
n += a &^ (1 << 0)
return n
}
func bitcompl32(a, b uint32) (n uint32) {
// amd64:"BTCL"
n += b ^ (1 << (a & 31))
// amd64:"BTCL\t[$]31"
n += a ^ (1 << 31)
// amd64:"BTCL\t[$]28"
n += a ^ (1 << 28)
// amd64:"XORL\t[$]1"
n += a ^ (1 << 0)
return n
}
// check direct operation on memory with constant source
func bitOpOnMem(a []uint32) {
// amd64:`ANDL\s[$]200,\s\([A-Z]+\)`
a[0] &= 200
// amd64:`ORL\s[$]220,\s4\([A-Z]+\)`
a[1] |= 220
// amd64:`XORL\s[$]240,\s8\([A-Z]+\)`
a[2] ^= 240
}
// Check AND masking on arm64 (Issue #19857)
func and_mask_1(a uint64) uint64 {
// arm64:`AND\t`
return a & ((1 << 63) - 1)
}
func and_mask_2(a uint64) uint64 {
// arm64:`AND\t`
return a & (1 << 63)
}
// Check generation of arm64 BIC/EON/ORN instructions
func op_bic(x, y uint32) uint32 {
// arm64:`BIC\t`,-`AND`
return x &^ y
}
func op_eon(x, y uint32) uint32 {
// arm64:`EON\t`,-`XOR`
return x ^ ^y
}
func op_orn(x, y uint32) uint32 {
// arm64:`ORN\t`,-`ORR`
return x | ^y
}