The compiler can do a fine job, and can also inline it.
From Jeremy Jackins's observation and rsc's recommendation in thread:
"Pure Go math.Abs outperforms assembly version"
https://groups.google.com/forum/#!topic/golang-dev/nP5mWvwAXZo
Updates #13095
Change-Id: I3066f8eaa327bb403173b29791cc8661d7c0532c
Reviewed-on: https://go-review.googlesource.com/16444
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
// Special cases are:
// Abs(±Inf) = +Inf
// Abs(NaN) = NaN
-func Abs(x float64) float64
-
-func abs(x float64) float64 {
+func Abs(x float64) float64 {
+ // TODO: once golang.org/issue/13905 is fixed, change this to:
+ // return Float64frombits(Float64bits(x) &^ (1 << 63))
+ // But for now, this generates better code and can also be inlined:
switch {
case x < 0:
return -x
+++ /dev/null
-// Copyright 2010 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.
-
-#include "textflag.h"
-
-// func Abs(x float64) float64
-TEXT ·Abs(SB),NOSPLIT,$0
- FMOVD x+0(FP), F0 // F0=x
- FABS // F0=|x|
- FMOVDP F0, ret+8(FP)
- RET
+++ /dev/null
-// Copyright 2010 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.
-
-#include "textflag.h"
-
-// func Abs(x float64) float64
-TEXT ·Abs(SB),NOSPLIT,$0
- MOVQ $(1<<63), BX
- MOVQ BX, X0 // movsd $(-0.0), x0
- MOVSD x+0(FP), X1
- ANDNPD X1, X0
- MOVSD X0, ret+8(FP)
- RET
+++ /dev/null
-// Copyright 2013 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.
-
-#include "abs_amd64.s"
+++ /dev/null
-// Copyright 2011 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.
-
-#include "textflag.h"
-
-TEXT ·Abs(SB),NOSPLIT,$0
- MOVW x_lo+0(FP), R0
- MOVW x_hi+4(FP), R1
- AND $((1<<31)-1), R1
- MOVW R0, ret_lo+8(FP)
- MOVW R1, ret_hi+12(FP)
- RET
+++ /dev/null
-// Copyright 2011 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.
-
-#include "textflag.h"
-
-TEXT ·Abs(SB),NOSPLIT,$0-16
- FMOVD x+0(FP), F3
- FABSD F3, F3
- FMOVD F3, ret+8(FP)
- RET
+++ /dev/null
-// Copyright 2011 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.
-
-// +build ppc64 ppc64le
-
-#include "textflag.h"
-
-TEXT ·Abs(SB),NOSPLIT,$0-16
- MOVD x+0(FP), R3
- MOVD $((1<<63)-1), R4
- AND R4, R3
- MOVD R3, ret+8(FP)
- RET