Source file test/codegen/floats.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  // This file contains codegen tests related to arithmetic
    10  // simplifications and optimizations on float types.
    11  // For codegen tests on integer types, see arithmetic.go.
    12  
    13  // --------------------- //
    14  //    Strength-reduce    //
    15  // --------------------- //
    16  
    17  func Mul2(f float64) float64 {
    18  	// 386/sse2:"ADDSD",-"MULSD"
    19  	// amd64:"ADDSD",-"MULSD"
    20  	// arm/7:"ADDD",-"MULD"
    21  	// arm64:"FADDD",-"FMULD"
    22  	// ppc64x:"FADD",-"FMUL"
    23  	// riscv64:"FADDD",-"FMULD"
    24  	return f * 2.0
    25  }
    26  
    27  func DivPow2(f1, f2, f3 float64) (float64, float64, float64) {
    28  	// 386/sse2:"MULSD",-"DIVSD"
    29  	// amd64:"MULSD",-"DIVSD"
    30  	// arm/7:"MULD",-"DIVD"
    31  	// arm64:"FMULD",-"FDIVD"
    32  	// ppc64x:"FMUL",-"FDIV"
    33  	// riscv64:"FMULD",-"FDIVD"
    34  	x := f1 / 16.0
    35  
    36  	// 386/sse2:"MULSD",-"DIVSD"
    37  	// amd64:"MULSD",-"DIVSD"
    38  	// arm/7:"MULD",-"DIVD"
    39  	// arm64:"FMULD",-"FDIVD"
    40  	// ppc64x:"FMUL",-"FDIVD"
    41  	// riscv64:"FMULD",-"FDIVD"
    42  	y := f2 / 0.125
    43  
    44  	// 386/sse2:"ADDSD",-"DIVSD",-"MULSD"
    45  	// amd64:"ADDSD",-"DIVSD",-"MULSD"
    46  	// arm/7:"ADDD",-"MULD",-"DIVD"
    47  	// arm64:"FADDD",-"FMULD",-"FDIVD"
    48  	// ppc64x:"FADD",-"FMUL",-"FDIV"
    49  	// riscv64:"FADDD",-"FMULD",-"FDIVD"
    50  	z := f3 / 0.5
    51  
    52  	return x, y, z
    53  }
    54  
    55  func indexLoad(b0 []float32, b1 float32, idx int) float32 {
    56  	// arm64:`FMOVS\s\(R[0-9]+\)\(R[0-9]+<<2\),\sF[0-9]+`
    57  	// loong64:`MOVF\s\(R[0-9]+\)\(R[0-9]+\),\sF[0-9]+`
    58  	return b0[idx] * b1
    59  }
    60  
    61  func indexStore(b0 []float64, b1 float64, idx int) {
    62  	// arm64:`FMOVD\sF[0-9]+,\s\(R[0-9]+\)\(R[0-9]+<<3\)`
    63  	// loong64:`MOVD\sF[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`
    64  	b0[idx] = b1
    65  }
    66  
    67  // ----------- //
    68  //    Fused    //
    69  // ----------- //
    70  
    71  func FusedAdd32(x, y, z float32) float32 {
    72  	// s390x:"FMADDS\t"
    73  	// ppc64x:"FMADDS\t"
    74  	// arm64:"FMADDS"
    75  	// loong64:"FMADDF\t"
    76  	// riscv64:"FMADDS\t"
    77  	// amd64/v3:"VFMADD231SS\t"
    78  	return x*y + z
    79  }
    80  
    81  func FusedSub32_a(x, y, z float32) float32 {
    82  	// s390x:"FMSUBS\t"
    83  	// ppc64x:"FMSUBS\t"
    84  	// riscv64:"FMSUBS\t"
    85  	// loong64:"FMSUBF\t"
    86  	return x*y - z
    87  }
    88  
    89  func FusedSub32_b(x, y, z float32) float32 {
    90  	// arm64:"FMSUBS"
    91  	// loong64:"FNMSUBF\t"
    92  	// riscv64:"FNMSUBS\t"
    93  	return z - x*y
    94  }
    95  
    96  func FusedAdd64(x, y, z float64) float64 {
    97  	// s390x:"FMADD\t"
    98  	// ppc64x:"FMADD\t"
    99  	// arm64:"FMADDD"
   100  	// loong64:"FMADDD\t"
   101  	// riscv64:"FMADDD\t"
   102  	// amd64/v3:"VFMADD231SD\t"
   103  	return x*y + z
   104  }
   105  
   106  func FusedSub64_a(x, y, z float64) float64 {
   107  	// s390x:"FMSUB\t"
   108  	// ppc64x:"FMSUB\t"
   109  	// riscv64:"FMSUBD\t"
   110  	// loong64:"FMSUBD\t"
   111  	return x*y - z
   112  }
   113  
   114  func FusedSub64_b(x, y, z float64) float64 {
   115  	// arm64:"FMSUBD"
   116  	// loong64:"FNMSUBD\t"
   117  	// riscv64:"FNMSUBD\t"
   118  	return z - x*y
   119  }
   120  
   121  func Cmp(f float64) bool {
   122  	// arm64:"FCMPD","(BGT|BLE|BMI|BPL)",-"CSET\tGT",-"CBZ"
   123  	return f > 4 || f < -4
   124  }
   125  
   126  func CmpZero64(f float64) bool {
   127  	// s390x:"LTDBR",-"FCMPU"
   128  	return f <= 0
   129  }
   130  
   131  func CmpZero32(f float32) bool {
   132  	// s390x:"LTEBR",-"CEBR"
   133  	return f <= 0
   134  }
   135  
   136  func CmpWithSub(a float64, b float64) bool {
   137  	f := a - b
   138  	// s390x:-"LTDBR"
   139  	return f <= 0
   140  }
   141  
   142  func CmpWithAdd(a float64, b float64) bool {
   143  	f := a + b
   144  	// s390x:-"LTDBR"
   145  	return f <= 0
   146  }
   147  
   148  // ---------------- //
   149  //    Non-floats    //
   150  // ---------------- //
   151  
   152  func ArrayZero() [16]byte {
   153  	// amd64:"MOVUPS"
   154  	var a [16]byte
   155  	return a
   156  }
   157  
   158  func ArrayCopy(a [16]byte) (b [16]byte) {
   159  	// amd64:"MOVUPS"
   160  	b = a
   161  	return
   162  }
   163  
   164  // ---------------- //
   165  //  Float Min/Max   //
   166  // ---------------- //
   167  
   168  func Float64Min(a, b float64) float64 {
   169  	// amd64:"MINSD"
   170  	// arm64:"FMIND"
   171  	// loong64:"FMIND"
   172  	// riscv64:"FMIN"
   173  	// ppc64/power9:"XSMINJDP"
   174  	// ppc64/power10:"XSMINJDP"
   175  	return min(a, b)
   176  }
   177  
   178  func Float64Max(a, b float64) float64 {
   179  	// amd64:"MINSD"
   180  	// arm64:"FMAXD"
   181  	// loong64:"FMAXD"
   182  	// riscv64:"FMAX"
   183  	// ppc64/power9:"XSMAXJDP"
   184  	// ppc64/power10:"XSMAXJDP"
   185  	return max(a, b)
   186  }
   187  
   188  func Float32Min(a, b float32) float32 {
   189  	// amd64:"MINSS"
   190  	// arm64:"FMINS"
   191  	// loong64:"FMINF"
   192  	// riscv64:"FMINS"
   193  	// ppc64/power9:"XSMINJDP"
   194  	// ppc64/power10:"XSMINJDP"
   195  	return min(a, b)
   196  }
   197  
   198  func Float32Max(a, b float32) float32 {
   199  	// amd64:"MINSS"
   200  	// arm64:"FMAXS"
   201  	// loong64:"FMAXF"
   202  	// riscv64:"FMAXS"
   203  	// ppc64/power9:"XSMAXJDP"
   204  	// ppc64/power10:"XSMAXJDP"
   205  	return max(a, b)
   206  }
   207  
   208  // ------------------------ //
   209  //  Constant Optimizations  //
   210  // ------------------------ //
   211  
   212  func Float32Constant() float32 {
   213  	// ppc64x/power8:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
   214  	// ppc64x/power9:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
   215  	// ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
   216  	return 49.0
   217  }
   218  
   219  func Float64Constant() float64 {
   220  	// ppc64x/power8:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
   221  	// ppc64x/power9:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
   222  	// ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
   223  	return 49.0
   224  }
   225  
   226  func Float32DenormalConstant() float32 {
   227  	// ppc64x:"FMOVS\t[$]f32\\.00400000\\(SB\\)"
   228  	return 0x1p-127
   229  }
   230  
   231  // A float64 constant which can be exactly represented as a
   232  // denormal float32 value. On ppc64x, denormal values cannot
   233  // be used with XXSPLTIDP.
   234  func Float64DenormalFloat32Constant() float64 {
   235  	// ppc64x:"FMOVD\t[$]f64\\.3800000000000000\\(SB\\)"
   236  	return 0x1p-127
   237  }
   238  
   239  func Float64ConstantStore(p *float64) {
   240  	// amd64: "MOVQ\t[$]4617801906721357038"
   241  	*p = 5.432
   242  }
   243  func Float32ConstantStore(p *float32) {
   244  	// amd64: "MOVL\t[$]1085133554"
   245  	*p = 5.432
   246  }
   247  

View as plain text