Source file test/codegen/rotate.go

     1  // asmcheck
     2  
     3  // Copyright 2018 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package codegen
     8  
     9  import "math/bits"
    10  
    11  // ------------------- //
    12  //    const rotates    //
    13  // ------------------- //
    14  
    15  func rot64(x uint64) uint64 {
    16  	var a uint64
    17  
    18  	// amd64:"ROLQ\t[$]7"
    19  	// ppc64:"ROTL\t[$]7"
    20  	// ppc64le:"ROTL\t[$]7"
    21  	// loong64: "ROTRV\t[$]57"
    22  	a += x<<7 | x>>57
    23  
    24  	// amd64:"ROLQ\t[$]8"
    25  	// arm64:"ROR\t[$]56"
    26  	// s390x:"RISBGZ\t[$]0, [$]63, [$]8, "
    27  	// ppc64:"ROTL\t[$]8"
    28  	// ppc64le:"ROTL\t[$]8"
    29  	// loong64: "ROTRV\t[$]56"
    30  	a += x<<8 + x>>56
    31  
    32  	// amd64:"ROLQ\t[$]9"
    33  	// arm64:"ROR\t[$]55"
    34  	// s390x:"RISBGZ\t[$]0, [$]63, [$]9, "
    35  	// ppc64:"ROTL\t[$]9"
    36  	// ppc64le:"ROTL\t[$]9"
    37  	// loong64: "ROTRV\t[$]55"
    38  	a += x<<9 ^ x>>55
    39  
    40  	// amd64:"ROLQ\t[$]10"
    41  	// arm64:"ROR\t[$]54"
    42  	// s390x:"RISBGZ\t[$]0, [$]63, [$]10, "
    43  	// ppc64:"ROTL\t[$]10"
    44  	// ppc64le:"ROTL\t[$]10"
    45  	// arm64:"ROR\t[$]54"
    46  	// s390x:"RISBGZ\t[$]0, [$]63, [$]10, "
    47  	// loong64: "ROTRV\t[$]54"
    48  	a += bits.RotateLeft64(x, 10)
    49  
    50  	return a
    51  }
    52  
    53  func rot32(x uint32) uint32 {
    54  	var a uint32
    55  
    56  	// amd64:"ROLL\t[$]7"
    57  	// arm:"MOVW\tR\\d+@>25"
    58  	// ppc64:"ROTLW\t[$]7"
    59  	// ppc64le:"ROTLW\t[$]7"
    60  	// loong64: "ROTR\t[$]25"
    61  	a += x<<7 | x>>25
    62  
    63  	// amd64:`ROLL\t[$]8`
    64  	// arm:"MOVW\tR\\d+@>24"
    65  	// arm64:"RORW\t[$]24"
    66  	// s390x:"RLL\t[$]8"
    67  	// ppc64:"ROTLW\t[$]8"
    68  	// ppc64le:"ROTLW\t[$]8"
    69  	// loong64: "ROTR\t[$]24"
    70  	a += x<<8 + x>>24
    71  
    72  	// amd64:"ROLL\t[$]9"
    73  	// arm:"MOVW\tR\\d+@>23"
    74  	// arm64:"RORW\t[$]23"
    75  	// s390x:"RLL\t[$]9"
    76  	// ppc64:"ROTLW\t[$]9"
    77  	// ppc64le:"ROTLW\t[$]9"
    78  	// loong64: "ROTR\t[$]23"
    79  	a += x<<9 ^ x>>23
    80  
    81  	// amd64:"ROLL\t[$]10"
    82  	// arm:"MOVW\tR\\d+@>22"
    83  	// arm64:"RORW\t[$]22"
    84  	// s390x:"RLL\t[$]10"
    85  	// ppc64:"ROTLW\t[$]10"
    86  	// ppc64le:"ROTLW\t[$]10"
    87  	// arm64:"RORW\t[$]22"
    88  	// s390x:"RLL\t[$]10"
    89  	// loong64: "ROTR\t[$]22"
    90  	a += bits.RotateLeft32(x, 10)
    91  
    92  	return a
    93  }
    94  
    95  func rot16(x uint16) uint16 {
    96  	var a uint16
    97  
    98  	// amd64:"ROLW\t[$]7"
    99  	a += x<<7 | x>>9
   100  
   101  	// amd64:`ROLW\t[$]8`
   102  	a += x<<8 + x>>8
   103  
   104  	// amd64:"ROLW\t[$]9"
   105  	a += x<<9 ^ x>>7
   106  
   107  	return a
   108  }
   109  
   110  func rot8(x uint8) uint8 {
   111  	var a uint8
   112  
   113  	// amd64:"ROLB\t[$]5"
   114  	a += x<<5 | x>>3
   115  
   116  	// amd64:`ROLB\t[$]6`
   117  	a += x<<6 + x>>2
   118  
   119  	// amd64:"ROLB\t[$]7"
   120  	a += x<<7 ^ x>>1
   121  
   122  	return a
   123  }
   124  
   125  // ----------------------- //
   126  //    non-const rotates    //
   127  // ----------------------- //
   128  
   129  func rot64nc(x uint64, z uint) uint64 {
   130  	var a uint64
   131  
   132  	z &= 63
   133  
   134  	// amd64:"ROLQ",-"AND"
   135  	// arm64:"ROR","NEG",-"AND"
   136  	// ppc64:"ROTL",-"NEG",-"AND"
   137  	// ppc64le:"ROTL",-"NEG",-"AND"
   138  	// loong64: "ROTRV", -"AND"
   139  	a += x<<z | x>>(64-z)
   140  
   141  	// amd64:"RORQ",-"AND"
   142  	// arm64:"ROR",-"NEG",-"AND"
   143  	// ppc64:"ROTL","NEG",-"AND"
   144  	// ppc64le:"ROTL","NEG",-"AND"
   145  	// loong64: "ROTRV", -"AND"
   146  	a += x>>z | x<<(64-z)
   147  
   148  	return a
   149  }
   150  
   151  func rot32nc(x uint32, z uint) uint32 {
   152  	var a uint32
   153  
   154  	z &= 31
   155  
   156  	// amd64:"ROLL",-"AND"
   157  	// arm64:"ROR","NEG",-"AND"
   158  	// ppc64:"ROTLW",-"NEG",-"AND"
   159  	// ppc64le:"ROTLW",-"NEG",-"AND"
   160  	// loong64: "ROTR", -"AND"
   161  	a += x<<z | x>>(32-z)
   162  
   163  	// amd64:"RORL",-"AND"
   164  	// arm64:"ROR",-"NEG",-"AND"
   165  	// ppc64:"ROTLW","NEG",-"AND"
   166  	// ppc64le:"ROTLW","NEG",-"AND"
   167  	// loong64: "ROTR", -"AND"
   168  	a += x>>z | x<<(32-z)
   169  
   170  	return a
   171  }
   172  
   173  func rot16nc(x uint16, z uint) uint16 {
   174  	var a uint16
   175  
   176  	z &= 15
   177  
   178  	// amd64:"ROLW",-"ANDQ"
   179  	a += x<<z | x>>(16-z)
   180  
   181  	// amd64:"RORW",-"ANDQ"
   182  	a += x>>z | x<<(16-z)
   183  
   184  	return a
   185  }
   186  
   187  func rot8nc(x uint8, z uint) uint8 {
   188  	var a uint8
   189  
   190  	z &= 7
   191  
   192  	// amd64:"ROLB",-"ANDQ"
   193  	a += x<<z | x>>(8-z)
   194  
   195  	// amd64:"RORB",-"ANDQ"
   196  	a += x>>z | x<<(8-z)
   197  
   198  	return a
   199  }
   200  
   201  // Issue 18254: rotate after inlining
   202  func f32(x uint32) uint32 {
   203  	// amd64:"ROLL\t[$]7"
   204  	return rot32nc(x, 7)
   205  }
   206  
   207  func doubleRotate(x uint64) uint64 {
   208  	x = (x << 5) | (x >> 59)
   209  	// amd64:"ROLQ\t[$]15"
   210  	// arm64:"ROR\t[$]49"
   211  	x = (x << 10) | (x >> 54)
   212  	return x
   213  }
   214  
   215  // --------------------------------------- //
   216  //    Combined Rotate + Masking operations //
   217  // --------------------------------------- //
   218  
   219  func checkMaskedRotate32(a []uint32, r int) {
   220  	i := 0
   221  
   222  	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
   223  	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
   224  	a[i] = bits.RotateLeft32(a[i], 16) & 0xFF0000
   225  	i++
   226  	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
   227  	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
   228  	a[i] = bits.RotateLeft32(a[i]&0xFF, 16)
   229  	i++
   230  	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
   231  	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
   232  	a[i] = bits.RotateLeft32(a[i], 4) & 0xFF0
   233  	i++
   234  	// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
   235  	// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
   236  	a[i] = bits.RotateLeft32(a[i]&0xFF0000, 16)
   237  	i++
   238  
   239  	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
   240  	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
   241  	a[i] = bits.RotateLeft32(a[i], r) & 0xFF0000
   242  	i++
   243  	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
   244  	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
   245  	a[i] = bits.RotateLeft32(a[i], r) & 0xFF00
   246  	i++
   247  
   248  	// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
   249  	// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
   250  	a[i] = bits.RotateLeft32(a[i], r) & 0xFFF00FFF
   251  	i++
   252  	// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
   253  	// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
   254  	a[i] = bits.RotateLeft32(a[i], 4) & 0xFFF00FFF
   255  	i++
   256  }
   257  
   258  // combined arithmetic and rotate on arm64
   259  func checkArithmeticWithRotate(a *[1000]uint64) {
   260  	// arm64: "AND\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
   261  	a[2] = a[1] & bits.RotateLeft64(a[0], 13)
   262  	// arm64: "ORR\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
   263  	a[5] = a[4] | bits.RotateLeft64(a[3], 13)
   264  	// arm64: "EOR\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
   265  	a[8] = a[7] ^ bits.RotateLeft64(a[6], 13)
   266  	// arm64: "MVN\tR[0-9]+@>51, R[0-9]+"
   267  	a[10] = ^bits.RotateLeft64(a[9], 13)
   268  	// arm64: "BIC\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
   269  	a[13] = a[12] &^ bits.RotateLeft64(a[11], 13)
   270  	// arm64: "EON\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
   271  	a[16] = a[15] ^ ^bits.RotateLeft64(a[14], 13)
   272  	// arm64: "ORN\tR[0-9]+@>51, R[0-9]+, R[0-9]+"
   273  	a[19] = a[18] | ^bits.RotateLeft64(a[17], 13)
   274  	// arm64: "TST\tR[0-9]+@>51, R[0-9]+"
   275  	if a[18]&bits.RotateLeft64(a[19], 13) == 0 {
   276  		a[20] = 1
   277  	}
   278  
   279  }
   280  

View as plain text