// asmcheck

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package codegen

import "math"

var sink64 [8]float64

func approx(x float64) {
	// amd64/v2:-".*x86HasSSE41" amd64/v3:-".*x86HasSSE41"
	// amd64:"ROUNDSD\t[$]2"
	// s390x:"FIDBR\t[$]6"
	// arm64:"FRINTPD"
	// ppc64:"FRIP"
	// ppc64le:"FRIP"
	// wasm:"F64Ceil"
	sink64[0] = math.Ceil(x)

	// amd64/v2:-".*x86HasSSE41" amd64/v3:-".*x86HasSSE41"
	// amd64:"ROUNDSD\t[$]1"
	// s390x:"FIDBR\t[$]7"
	// arm64:"FRINTMD"
	// ppc64:"FRIM"
	// ppc64le:"FRIM"
	// wasm:"F64Floor"
	sink64[1] = math.Floor(x)

	// s390x:"FIDBR\t[$]1"
	// arm64:"FRINTAD"
	// ppc64:"FRIN"
	// ppc64le:"FRIN"
	sink64[2] = math.Round(x)

	// amd64/v2:-".*x86HasSSE41" amd64/v3:-".*x86HasSSE41"
	// amd64:"ROUNDSD\t[$]3"
	// s390x:"FIDBR\t[$]5"
	// arm64:"FRINTZD"
	// ppc64:"FRIZ"
	// ppc64le:"FRIZ"
	// wasm:"F64Trunc"
	sink64[3] = math.Trunc(x)

	// amd64/v2:-".*x86HasSSE41" amd64/v3:-".*x86HasSSE41"
	// amd64:"ROUNDSD\t[$]0"
	// s390x:"FIDBR\t[$]4"
	// arm64:"FRINTND"
	// wasm:"F64Nearest"
	sink64[4] = math.RoundToEven(x)
}

func sqrt(x float64) float64 {
	// amd64:"SQRTSD"
	// 386/sse2:"SQRTSD" 386/softfloat:-"SQRTD"
	// arm64:"FSQRTD"
	// arm/7:"SQRTD"
	// mips/hardfloat:"SQRTD" mips/softfloat:-"SQRTD"
	// mips64/hardfloat:"SQRTD" mips64/softfloat:-"SQRTD"
	// wasm:"F64Sqrt"
	return math.Sqrt(x)
}

func sqrt32(x float32) float32 {
	// amd64:"SQRTSS"
	// 386/sse2:"SQRTSS" 386/softfloat:-"SQRTS"
	// arm64:"FSQRTS"
	// arm/7:"SQRTF"
	// mips/hardfloat:"SQRTF" mips/softfloat:-"SQRTF"
	// mips64/hardfloat:"SQRTF" mips64/softfloat:-"SQRTF"
	// wasm:"F32Sqrt"
	return float32(math.Sqrt(float64(x)))
}

// Check that it's using integer registers
func abs(x, y float64) {
	// amd64:"BTRQ\t[$]63"
	// arm64:"FABSD\t"
	// s390x:"LPDFR\t",-"MOVD\t"     (no integer load/store)
	// ppc64:"FABS\t"
	// ppc64le:"FABS\t"
	// riscv64:"FABSD\t"
	// wasm:"F64Abs"
	// arm/6:"ABSD\t"
	sink64[0] = math.Abs(x)

	// amd64:"BTRQ\t[$]63","PXOR"    (TODO: this should be BTSQ)
	// s390x:"LNDFR\t",-"MOVD\t"     (no integer load/store)
	// ppc64:"FNABS\t"
	// ppc64le:"FNABS\t"
	sink64[1] = -math.Abs(y)
}

// Check that it's using integer registers
func abs32(x float32) float32 {
	// s390x:"LPDFR",-"LDEBR",-"LEDBR"     (no float64 conversion)
	return float32(math.Abs(float64(x)))
}

// Check that it's using integer registers
func copysign(a, b, c float64) {
	// amd64:"BTRQ\t[$]63","ANDQ","ORQ"
	// s390x:"CPSDR",-"MOVD"         (no integer load/store)
	// ppc64:"FCPSGN"
	// ppc64le:"FCPSGN"
	// riscv64:"FSGNJD"
	// wasm:"F64Copysign"
	sink64[0] = math.Copysign(a, b)

	// amd64:"BTSQ\t[$]63"
	// s390x:"LNDFR\t",-"MOVD\t"     (no integer load/store)
	// ppc64:"FCPSGN"
	// ppc64le:"FCPSGN"
	// riscv64:"FSGNJD"
	// arm64:"ORR", -"AND"
	sink64[1] = math.Copysign(c, -1)

	// Like math.Copysign(c, -1), but with integer operations. Useful
	// for platforms that have a copysign opcode to see if it's detected.
	// s390x:"LNDFR\t",-"MOVD\t"     (no integer load/store)
	sink64[2] = math.Float64frombits(math.Float64bits(a) | 1<<63)

	// amd64:"ANDQ","ORQ"
	// s390x:"CPSDR\t",-"MOVD\t"     (no integer load/store)
	// ppc64:"FCPSGN"
	// ppc64le:"FCPSGN"
	// riscv64:"FSGNJD"
	sink64[3] = math.Copysign(-1, c)
}

func fma(x, y, z float64) float64 {
	// amd64/v3:-".*x86HasFMA"
	// amd64:"VFMADD231SD"
	// arm/6:"FMULAD"
	// arm64:"FMADDD"
	// s390x:"FMADD"
	// ppc64:"FMADD"
	// ppc64le:"FMADD"
	// riscv64:"FMADDD"
	return math.FMA(x, y, z)
}

func fms(x, y, z float64) float64 {
	// riscv64:"FMSUBD"
	return math.FMA(x, y, -z)
}

func fnma(x, y, z float64) float64 {
	// riscv64:"FNMADDD"
	return math.FMA(-x, y, z)
}

func fnms(x, y, z float64) float64 {
	// riscv64:"FNMSUBD"
	return math.FMA(x, -y, -z)
}

func fromFloat64(f64 float64) uint64 {
	// amd64:"MOVQ\tX.*, [^X].*"
	// arm64:"FMOVD\tF.*, R.*"
	// ppc64:"MFVSRD"
	// ppc64le:"MFVSRD"
	return math.Float64bits(f64+1) + 1
}

func fromFloat32(f32 float32) uint32 {
	// amd64:"MOVL\tX.*, [^X].*"
	// arm64:"FMOVS\tF.*, R.*"
	return math.Float32bits(f32+1) + 1
}

func toFloat64(u64 uint64) float64 {
	// amd64:"MOVQ\t[^X].*, X.*"
	// arm64:"FMOVD\tR.*, F.*"
	// ppc64:"MTVSRD"
	// ppc64le:"MTVSRD"
	return math.Float64frombits(u64+1) + 1
}

func toFloat32(u32 uint32) float32 {
	// amd64:"MOVL\t[^X].*, X.*"
	// arm64:"FMOVS\tR.*, F.*"
	return math.Float32frombits(u32+1) + 1
}

// Test that comparisons with constants converted to float
// are evaluated at compile-time

func constantCheck64() bool {
	// amd64:"(MOVB\t[$]0)|(XORL\t[A-Z][A-Z0-9]+, [A-Z][A-Z0-9]+)",-"FCMP",-"MOVB\t[$]1"
	// s390x:"MOV(B|BZ|D)\t[$]0,",-"FCMPU",-"MOV(B|BZ|D)\t[$]1,"
	return 0.5 == float64(uint32(1)) || 1.5 > float64(uint64(1<<63))
}

func constantCheck32() bool {
	// amd64:"MOV(B|L)\t[$]1",-"FCMP",-"MOV(B|L)\t[$]0"
	// s390x:"MOV(B|BZ|D)\t[$]1,",-"FCMPU",-"MOV(B|BZ|D)\t[$]0,"
	return float32(0.5) <= float32(int64(1)) && float32(1.5) >= float32(int32(-1<<31))
}

// Test that integer constants are converted to floating point constants
// at compile-time

func constantConvert32(x float32) float32 {
	// amd64:"MOVSS\t[$]f32.3f800000\\(SB\\)"
	// s390x:"FMOVS\t[$]f32.3f800000\\(SB\\)"
	// ppc64:"FMOVS\t[$]f32.3f800000\\(SB\\)"
	// ppc64le:"FMOVS\t[$]f32.3f800000\\(SB\\)"
	// arm64:"FMOVS\t[$]\\(1.0\\)"
	if x > math.Float32frombits(0x3f800000) {
		return -x
	}
	return x
}

func constantConvertInt32(x uint32) uint32 {
	// amd64:-"MOVSS"
	// s390x:-"FMOVS"
	// ppc64:-"FMOVS"
	// ppc64le:-"FMOVS"
	// arm64:-"FMOVS"
	if x > math.Float32bits(1) {
		return -x
	}
	return x
}

func nanGenerate64() float64 {
	// Test to make sure we don't generate a NaN while constant propagating.
	// See issue 36400.
	zero := 0.0
	// amd64:-"DIVSD"
	inf := 1 / zero // +inf. We can constant propagate this one.
	negone := -1.0

	// amd64:"DIVSD"
	z0 := zero / zero
	// amd64:"MULSD"
	z1 := zero * inf
	// amd64:"SQRTSD"
	z2 := math.Sqrt(negone)
	return z0 + z1 + z2
}

func nanGenerate32() float32 {
	zero := float32(0.0)
	// amd64:-"DIVSS"
	inf := 1 / zero // +inf. We can constant propagate this one.

	// amd64:"DIVSS"
	z0 := zero / zero
	// amd64:"MULSS"
	z1 := zero * inf
	return z0 + z1
}
