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

View as plain text