Skip to content

Commit

Permalink
add Int support to amd64 and fix issue with structs not being copied (#…
Browse files Browse the repository at this point in the history
…288)

Closes #289
  • Loading branch information
TotallyGamerJet authored and hajimehoshi committed Oct 19, 2024
1 parent ed3ae3d commit f719fc5
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
20 changes: 4 additions & 16 deletions struct_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFl
return keepAlive
}

func postMerger(t reflect.Type) bool {
func postMerger(t reflect.Type) (passInMemory bool) {
// (c) If the size of the aggregate exceeds two eightbytes and the first eight- byte isn’t SSE or any other
// eightbyte isn’t SSEUP, the whole argument is passed in memory.
if t.Kind() != reflect.Struct {
Expand All @@ -120,19 +120,7 @@ func postMerger(t reflect.Type) bool {
if t.Size() <= 2*8 {
return false
}
first := getFirst(t).Kind()
if first != reflect.Float32 && first != reflect.Float64 {
return false
}
return true
}

func getFirst(t reflect.Type) reflect.Type {
first := t.Field(0).Type
if first.Kind() == reflect.Struct {
return getFirst(first)
}
return first
return true // Go does not have an SSE/SEEUP type so this is always true
}

func tryPlaceRegister(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) (ok bool) {
Expand Down Expand Up @@ -196,7 +184,7 @@ func tryPlaceRegister(v reflect.Value, addFloat func(uintptr), addInt func(uintp
val |= uint64(f.Int()&0xFFFF_FFFF) << shift
shift += 32
class |= _INTEGER
case reflect.Int64:
case reflect.Int64, reflect.Int:
val = uint64(f.Int())
shift = 64
class = _INTEGER
Expand All @@ -212,7 +200,7 @@ func tryPlaceRegister(v reflect.Value, addFloat func(uintptr), addInt func(uintp
val |= f.Uint() << shift
shift += 32
class |= _INTEGER
case reflect.Uint64:
case reflect.Uint64, reflect.Uint:
val = f.Uint()
shift = 64
class = _INTEGER
Expand Down
23 changes: 23 additions & 0 deletions struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package purego_test

import (
"math"
"os"
"path/filepath"
"runtime"
Expand Down Expand Up @@ -440,6 +441,28 @@ func TestRegisterFunc_structArgs(t *testing.T) {
t.Fatalf("InitWithContentRect returned %d wanted %#x", ret, expectedUnsigned)
}
}
{
type GoInt4 struct {
A, B, C, D int
}
var GoInt4Fn func(GoInt4) int
purego.RegisterLibFunc(&GoInt4Fn, lib, "GoInt4")
const expected = math.MaxInt - 52 - 3 + 4
if ret := GoInt4Fn(GoInt4{math.MaxInt, -52, 3, 4}); ret != expected {
t.Fatalf("GoInt4Fn returned %d wanted %#x", ret, expected)
}
}
{
type GoUint4 struct {
A, B, C, D uint
}
var GoUint4Fn func(GoUint4) uint
purego.RegisterLibFunc(&GoUint4Fn, lib, "GoUint4")
const expected = 1_000_000 + 53 + 71 + 8
if ret := GoUint4Fn(GoUint4{1_000_000, 53, 71, 8}); ret != expected {
t.Fatalf("GoUint4Fn returned %d wanted %#x", ret, expected)
}
}
}

func TestRegisterFunc_structReturns(t *testing.T) {
Expand Down
23 changes: 23 additions & 0 deletions testdata/structtest/struct_test.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors

#include "stdint.h"

#if defined(__x86_64__) || defined(__aarch64__)
typedef int64_t GoInt;
typedef uint64_t GoUint;
#endif

// Empty is empty
struct Empty {};

Expand Down Expand Up @@ -325,3 +332,19 @@ unsigned long InitWithContentRect(int *win, struct Content c, int style, int bac
return 0xF1A6; // FLAG
return (unsigned long)(c.point.x + c.point.y + c.size.width + c.size.height) / (style - backing);
}

struct GoInt4 {
GoInt a, b, c, d;
};

GoInt GoInt4(struct GoInt4 g) {
return g.a + g.b - g.c + g.d;
}

struct GoUint4 {
GoUint a, b, c, d;
};

GoUint GoUint4(struct GoUint4 g) {
return g.a + g.b + g.c + g.d;
}

0 comments on commit f719fc5

Please # to comment.