github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/test/armimm.go (about)

     1  // run
     2  
     3  // Copyright 2017 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  // This file tests the splitting of constants into
     8  // multiple immediates on arm.
     9  
    10  package main
    11  
    12  import "fmt"
    13  
    14  const c32a = 0x00aa00dd
    15  const c32s = 0x00ffff00
    16  const c64a = 0x00aa00dd55000066
    17  const c64s = 0x00ffff00004fff00
    18  
    19  //go:noinline
    20  func add32a(x uint32) uint32 {
    21  	return x + c32a
    22  }
    23  
    24  //go:noinline
    25  func add32s(x uint32) uint32 {
    26  	return x + c32s
    27  }
    28  
    29  //go:noinline
    30  func sub32a(x uint32) uint32 {
    31  	return x - c32a
    32  }
    33  
    34  //go:noinline
    35  func sub32s(x uint32) uint32 {
    36  	return x - c32s
    37  }
    38  
    39  //go:noinline
    40  func or32(x uint32) uint32 {
    41  	return x | c32a
    42  }
    43  
    44  //go:noinline
    45  func xor32(x uint32) uint32 {
    46  	return x ^ c32a
    47  }
    48  
    49  //go:noinline
    50  func subr32a(x uint32) uint32 {
    51  	return c32a - x
    52  }
    53  
    54  //go:noinline
    55  func subr32s(x uint32) uint32 {
    56  	return c32s - x
    57  }
    58  
    59  //go:noinline
    60  func bic32(x uint32) uint32 {
    61  	return x &^ c32a
    62  }
    63  
    64  //go:noinline
    65  func add64a(x uint64) uint64 {
    66  	return x + c64a
    67  }
    68  
    69  //go:noinline
    70  func add64s(x uint64) uint64 {
    71  	return x + c64s
    72  }
    73  
    74  //go:noinline
    75  func sub64a(x uint64) uint64 {
    76  	return x - c64a
    77  }
    78  
    79  //go:noinline
    80  func sub64s(x uint64) uint64 {
    81  	return x - c64s
    82  }
    83  
    84  //go:noinline
    85  func or64(x uint64) uint64 {
    86  	return x | c64a
    87  }
    88  
    89  //go:noinline
    90  func xor64(x uint64) uint64 {
    91  	return x ^ c64a
    92  }
    93  
    94  //go:noinline
    95  func subr64a(x uint64) uint64 {
    96  	return c64a - x
    97  }
    98  
    99  //go:noinline
   100  func subr64s(x uint64) uint64 {
   101  	return c64s - x
   102  }
   103  
   104  //go:noinline
   105  func bic64(x uint64) uint64 {
   106  	return x &^ c64a
   107  }
   108  
   109  // Note: x-c gets rewritten to x+(-c), so SUB and SBC are not directly testable.
   110  // I disabled that rewrite rule before running this test.
   111  
   112  func main() {
   113  	test32()
   114  	test64()
   115  }
   116  
   117  func test32() {
   118  	var a uint32 = 0x11111111
   119  	var want, got uint32
   120  	if want, got = a+c32a, add32a(a); got != want {
   121  		panic(fmt.Sprintf("add32a(%x) = %x, want %x", a, got, want))
   122  	}
   123  	if want, got = a+c32s, add32s(a); got != want {
   124  		panic(fmt.Sprintf("add32s(%x) = %x, want %x", a, got, want))
   125  	}
   126  	if want, got = a-c32a, sub32a(a); got != want {
   127  		panic(fmt.Sprintf("sub32a(%x) = %x, want %x", a, got, want))
   128  	}
   129  	if want, got = a-c32s, sub32s(a); got != want {
   130  		panic(fmt.Sprintf("sub32s(%x) = %x, want %x", a, got, want))
   131  	}
   132  	if want, got = a|c32a, or32(a); got != want {
   133  		panic(fmt.Sprintf("or32(%x) = %x, want %x", a, got, want))
   134  	}
   135  	if want, got = a^c32a, xor32(a); got != want {
   136  		panic(fmt.Sprintf("xor32(%x) = %x, want %x", a, got, want))
   137  	}
   138  	if want, got = c32a-a, subr32a(a); got != want {
   139  		panic(fmt.Sprintf("subr32a(%x) = %x, want %x", a, got, want))
   140  	}
   141  	if want, got = c32s-a, subr32s(a); got != want {
   142  		panic(fmt.Sprintf("subr32s(%x) = %x, want %x", a, got, want))
   143  	}
   144  	if want, got = a&^c32a, bic32(a); got != want {
   145  		panic(fmt.Sprintf("bic32(%x) = %x, want %x", a, got, want))
   146  	}
   147  }
   148  
   149  func test64() {
   150  	var a uint64 = 0x1111111111111111
   151  	var want, got uint64
   152  	if want, got = a+c64a, add64a(a); got != want {
   153  		panic(fmt.Sprintf("add64a(%x) = %x, want %x", a, got, want))
   154  	}
   155  	if want, got = a+c64s, add64s(a); got != want {
   156  		panic(fmt.Sprintf("add64s(%x) = %x, want %x", a, got, want))
   157  	}
   158  	if want, got = a-c64a, sub64a(a); got != want {
   159  		panic(fmt.Sprintf("sub64a(%x) = %x, want %x", a, got, want))
   160  	}
   161  	if want, got = a-c64s, sub64s(a); got != want {
   162  		panic(fmt.Sprintf("sub64s(%x) = %x, want %x", a, got, want))
   163  	}
   164  	if want, got = a|c64a, or64(a); got != want {
   165  		panic(fmt.Sprintf("or64(%x) = %x, want %x", a, got, want))
   166  	}
   167  	if want, got = a^c64a, xor64(a); got != want {
   168  		panic(fmt.Sprintf("xor64(%x) = %x, want %x", a, got, want))
   169  	}
   170  	if want, got = c64a-a, subr64a(a); got != want {
   171  		panic(fmt.Sprintf("subr64a(%x) = %x, want %x", a, got, want))
   172  	}
   173  	if want, got = c64s-a, subr64s(a); got != want {
   174  		panic(fmt.Sprintf("subr64s(%x) = %x, want %x", a, got, want))
   175  	}
   176  	if want, got = a&^c64a, bic64(a); got != want {
   177  		panic(fmt.Sprintf("bic64(%x) = %x, want %x", a, got, want))
   178  	}
   179  }