mirror of
https://github.com/golang/go
synced 2024-11-07 23:56:16 -07:00
math: ensure Erfc is not called with out-of-expected-range arguments on s390x
The existing implementation produces correct results with a wide range of inputs, but invalid results asymptotically. With this change we ensure correct asymptotic results on s390x Fixes #26477 Change-Id: I760c1f8177f7cab2d7622ab9a926dfb1f8113b49 Reviewed-on: https://go-review.googlesource.com/127119 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
db810b6e39
commit
f04a002e5a
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
#define NegInf 0xFFF0000000000000
|
#define Neg2p11 0xC000E147AE147AE1
|
||||||
|
#define Pos15 0x402E
|
||||||
|
|
||||||
// Minimax polynomial coefficients and other constants
|
// Minimax polynomial coefficients and other constants
|
||||||
DATA ·erfcrodataL38<> + 0(SB)/8, $.234875460637085087E-01
|
DATA ·erfcrodataL38<> + 0(SB)/8, $.234875460637085087E-01
|
||||||
@ -136,21 +137,24 @@ GLOBL ·erfctab2069<> + 0(SB), RODATA, $128
|
|||||||
// Erfc(NaN) = NaN
|
// Erfc(NaN) = NaN
|
||||||
// The algorithm used is minimax polynomial approximation
|
// The algorithm used is minimax polynomial approximation
|
||||||
// with coefficients determined with a Remez exchange algorithm.
|
// with coefficients determined with a Remez exchange algorithm.
|
||||||
|
// This assembly implementation handles inputs in the range [-2.11, +15].
|
||||||
|
// For all other inputs we call the generic Go implementation.
|
||||||
|
|
||||||
TEXT ·erfcAsm(SB), NOSPLIT, $0-16
|
TEXT ·erfcAsm(SB), NOSPLIT|NOFRAME, $0-16
|
||||||
//special case Erfc(+Inf) = 0
|
|
||||||
MOVD x+0(FP), R1
|
MOVD x+0(FP), R1
|
||||||
MOVD $NegInf, R2
|
MOVD $Neg2p11, R2
|
||||||
CMPUBEQ R1, R2, erfcIsPosInf
|
CMPUBGT R1, R2, usego
|
||||||
|
|
||||||
FMOVD x+0(FP), F0
|
FMOVD x+0(FP), F0
|
||||||
MOVD $·erfcrodataL38<>+0(SB), R9
|
MOVD $·erfcrodataL38<>+0(SB), R9
|
||||||
WORD $0xB3CD0010 //lgdr %r1, %f0
|
|
||||||
FMOVD F0, F2
|
FMOVD F0, F2
|
||||||
SRAD $48, R1
|
SRAD $48, R1
|
||||||
MOVH $0x3FFF, R3
|
|
||||||
MOVH R1, R2
|
MOVH R1, R2
|
||||||
ANDW $0x7FFF, R1
|
ANDW $0x7FFF, R1
|
||||||
|
MOVH $Pos15, R3
|
||||||
|
CMPW R1, R3
|
||||||
|
BGT usego
|
||||||
|
MOVH $0x3FFF, R3
|
||||||
MOVW R1, R6
|
MOVW R1, R6
|
||||||
MOVW R3, R7
|
MOVW R3, R7
|
||||||
CMPBGT R6, R7, L2
|
CMPBGT R6, R7, L2
|
||||||
@ -523,8 +527,5 @@ L18:
|
|||||||
L25:
|
L25:
|
||||||
FMOVD 568(R9), F2
|
FMOVD 568(R9), F2
|
||||||
BR L1
|
BR L1
|
||||||
erfcIsPosInf:
|
usego:
|
||||||
FMOVD $(2.0), F1
|
BR ·erfc(SB)
|
||||||
FMOVD F1, ret+8(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user