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  	return x*y + z
    78  }
    79  
    80  func FusedSub32_a(x, y, z float32) float32 {
    81  	// s390x:"FMSUBS\t"
    82  	// ppc64x:"FMSUBS\t"
    83  	// riscv64:"FMSUBS\t"
    84  	// loong64:"FMSUBF\t"
    85  	return x*y - z
    86  }
    87  
    88  func FusedSub32_b(x, y, z float32) float32 {
    89  	// arm64:"FMSUBS"
    90  	// loong64:"FNMSUBF\t"
    91  	// riscv64:"FNMSUBS\t"
    92  	return z - x*y
    93  }
    94  
    95  func FusedAdd64(x, y, z float64) float64 {
    96  	// s390x:"FMADD\t"
    97  	// ppc64x:"FMADD\t"
    98  	// arm64:"FMADDD"
    99  	// loong64:"FMADDD\t"
   100  	// riscv64:"FMADDD\t"
   101  	return x*y + z
   102  }
   103  
   104  func FusedSub64_a(x, y, z float64) float64 {
   105  	// s390x:"FMSUB\t"
   106  	// ppc64x:"FMSUB\t"
   107  	// riscv64:"FMSUBD\t"
   108  	// loong64:"FMSUBD\t"
   109  	return x*y - z
   110  }
   111  
   112  func FusedSub64_b(x, y, z float64) float64 {
   113  	// arm64:"FMSUBD"
   114  	// loong64:"FNMSUBD\t"
   115  	// riscv64:"FNMSUBD\t"
   116  	return z - x*y
   117  }
   118  
   119  func Cmp(f float64) bool {
   120  	// arm64:"FCMPD","(BGT|BLE|BMI|BPL)",-"CSET\tGT",-"CBZ"
   121  	return f > 4 || f < -4
   122  }
   123  
   124  func CmpZero64(f float64) bool {
   125  	// s390x:"LTDBR",-"FCMPU"
   126  	return f <= 0
   127  }
   128  
   129  func CmpZero32(f float32) bool {
   130  	// s390x:"LTEBR",-"CEBR"
   131  	return f <= 0
   132  }
   133  
   134  func CmpWithSub(a float64, b float64) bool {
   135  	f := a - b
   136  	// s390x:-"LTDBR"
   137  	return f <= 0
   138  }
   139  
   140  func CmpWithAdd(a float64, b float64) bool {
   141  	f := a + b
   142  	// s390x:-"LTDBR"
   143  	return f <= 0
   144  }
   145  
   146  // ---------------- //
   147  //    Non-floats    //
   148  // ---------------- //
   149  
   150  // We should make sure that the compiler doesn't generate floating point
   151  // instructions for non-float operations on Plan 9, because floating point
   152  // operations are not allowed in the note handler.
   153  
   154  func ArrayZero() [16]byte {
   155  	// amd64:"MOVUPS"
   156  	// plan9/amd64/:-"MOVUPS"
   157  	var a [16]byte
   158  	return a
   159  }
   160  
   161  func ArrayCopy(a [16]byte) (b [16]byte) {
   162  	// amd64:"MOVUPS"
   163  	// plan9/amd64/:-"MOVUPS"
   164  	b = a
   165  	return
   166  }
   167  
   168  // ---------------- //
   169  //  Float Min/Max   //
   170  // ---------------- //
   171  
   172  func Float64Min(a, b float64) float64 {
   173  	// amd64:"MINSD"
   174  	// arm64:"FMIND"
   175  	// loong64:"FMIND"
   176  	// riscv64:"FMIN"
   177  	// ppc64/power9:"XSMINJDP"
   178  	// ppc64/power10:"XSMINJDP"
   179  	return min(a, b)
   180  }
   181  
   182  func Float64Max(a, b float64) float64 {
   183  	// amd64:"MINSD"
   184  	// arm64:"FMAXD"
   185  	// loong64:"FMAXD"
   186  	// riscv64:"FMAX"
   187  	// ppc64/power9:"XSMAXJDP"
   188  	// ppc64/power10:"XSMAXJDP"
   189  	return max(a, b)
   190  }
   191  
   192  func Float32Min(a, b float32) float32 {
   193  	// amd64:"MINSS"
   194  	// arm64:"FMINS"
   195  	// loong64:"FMINF"
   196  	// riscv64:"FMINS"
   197  	// ppc64/power9:"XSMINJDP"
   198  	// ppc64/power10:"XSMINJDP"
   199  	return min(a, b)
   200  }
   201  
   202  func Float32Max(a, b float32) float32 {
   203  	// amd64:"MINSS"
   204  	// arm64:"FMAXS"
   205  	// loong64:"FMAXF"
   206  	// riscv64:"FMAXS"
   207  	// ppc64/power9:"XSMAXJDP"
   208  	// ppc64/power10:"XSMAXJDP"
   209  	return max(a, b)
   210  }
   211  
   212  // ------------------------ //
   213  //  Constant Optimizations  //
   214  // ------------------------ //
   215  
   216  func Float32Constant() float32 {
   217  	// ppc64x/power8:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
   218  	// ppc64x/power9:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
   219  	// ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
   220  	return 49.0
   221  }
   222  
   223  func Float64Constant() float64 {
   224  	// ppc64x/power8:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
   225  	// ppc64x/power9:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
   226  	// ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
   227  	return 49.0
   228  }
   229  
   230  func Float32DenormalConstant() float32 {
   231  	// ppc64x:"FMOVS\t[$]f32\\.00400000\\(SB\\)"
   232  	return 0x1p-127
   233  }
   234  
   235  // A float64 constant which can be exactly represented as a
   236  // denormal float32 value. On ppc64x, denormal values cannot
   237  // be used with XXSPLTIDP.
   238  func Float64DenormalFloat32Constant() float64 {
   239  	// ppc64x:"FMOVD\t[$]f64\\.3800000000000000\\(SB\\)"
   240  	return 0x1p-127
   241  }
   242  
   243  func Float64ConstantStore(p *float64) {
   244  	// amd64: "MOVQ\t[$]4617801906721357038"
   245  	*p = 5.432
   246  }
   247  func Float32ConstantStore(p *float32) {
   248  	// amd64: "MOVL\t[$]1085133554"
   249  	*p = 5.432
   250  }
   251  

View as plain text