Commit 0b7a77ea authored by cznic's avatar cznic
Browse files

windows: use assembler for strtod(3) where needed, updates #49

parent b70fb7ce
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -7702,17 +7702,6 @@ func X__mingw_strtod(t *TLS, s uintptr, p uintptr) float64 {
	return Xstrtod(t, s, p)
}

func Xstrtod(t *TLS, s uintptr, p uintptr) float64 {
	if __ccgo_strace {
		trc("tls=%v s=%v p=%v, (%v:)", t, s, p, origin(2))
	}
	_, r2, err := procStrtod.Call(uintptr(s), uintptr(p))
	if err != windows.NOERROR {
		t.setErrno(err)
	}
	return math.Float64frombits(uint64(r2))
}

// int vsnprintf(char *str, size_t size, const char *format, va_list ap);
func X_vsnprintf(t *TLS, str uintptr, size types.Size_t, format, ap uintptr) int32 {
	if __ccgo_strace {
+12 −0
Original line number Diff line number Diff line
@@ -727,3 +727,15 @@ func Xstrspn(tls *TLS, s uintptr, c uintptr) size_t { /* strspn.c:6:8: */
	}
	return size_t((int32(s) - int32(a)) / 1)
}

// Defined in libc_windows_386.s
func callStrtod(fn uintptr, s uintptr, p uintptr) float64

func Xstrtod(t *TLS, s uintptr, p uintptr) float64 {
	if __ccgo_strace {
		trc("tls=%v s=%v p=%v, (%v:)", t, s, p, origin(2))
	}
	// We use the assembly bridge to call the function pointer directly.
	// This ensures we capture the float return value from ST(0).
	return callStrtod(procStrtod.Addr(), s, p)
}

libc_windows_386.s

0 → 100644
+26 −0
Original line number Diff line number Diff line
#include "textflag.h"

// func callStrtod(fn uintptr, s uintptr, p uintptr) float64
TEXT ·callStrtod(SB), NOSPLIT, $0
	// 1. Load arguments from Go stack
	MOVL	fn+0(FP), AX	// Function pointer
	MOVL	s+4(FP), CX	// String pointer
	MOVL	p+8(FP), DX	// Endptr pointer

	// 2. Setup C stack for __cdecl
	// We push 8 bytes (2 args).
	SUBL	$8, SP
	MOVL	DX, 4(SP)	// Push endptr (2nd arg)
	MOVL	CX, 0(SP)	// Push str (1st arg)

	// 3. Call the C function
	CALL	AX

	// 4. Clean up stack (__cdecl requires caller to clean)
	ADDL	$8, SP

	// 5. Store FPU result (ST0) into Go return slot
	// FMOVD with destination memory implies FSTP (store and pop)
	FMOVD	F0, ret+12(FP)
	
	RET
+15 −2
Original line number Diff line number Diff line
@@ -6,11 +6,13 @@ package libc // import "modernc.org/libc"

import (
	"golang.org/x/sys/windows"
	"modernc.org/libc/errno"
	"modernc.org/libc/sys/types"
	"math"
	"os"
	"strings"
	"unsafe"

	"modernc.org/libc/errno"
	"modernc.org/libc/sys/types"
)

// int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
@@ -627,3 +629,14 @@ func Xstrspn(tls *TLS, s uintptr, c uintptr) size_t { /* strspn.c:6:8: */
	}
	return size_t((int64(s) - int64(a)) / 1)
}

func Xstrtod(t *TLS, s uintptr, p uintptr) float64 {
	if __ccgo_strace {
		trc("tls=%v s=%v p=%v, (%v:)", t, s, p, origin(2))
	}
	_, r2, err := procStrtod.Call(uintptr(s), uintptr(p))
	if err != windows.NOERROR {
		t.setErrno(err)
	}
	return math.Float64frombits(uint64(r2))
}
+10 −0
Original line number Diff line number Diff line
@@ -627,3 +627,13 @@ func Xstrspn(tls *TLS, s uintptr, c uintptr) size_t { /* strspn.c:6:8: */
	}
	return size_t((int64(s) - int64(a)) / 1)
}

// Defined in libc_windows_arm64.s
func callStrtod(fn uintptr, s uintptr, p uintptr) float64

func Xstrtod(t *TLS, s uintptr, p uintptr) float64 {
	if __ccgo_strace {
		trc("tls=%v s=%v p=%v, (%v:)", t, s, p, origin(2))
	}
	return callStrtod(procStrtod.Addr(), s, p)
}
Loading